Commit Graph
32 Commits
Author SHA1 Message Date
florian.wildeandClaude Opus 5.5 4219701b29 feat(anmeldung): lokale Benutzerkonten mit Pflicht-TOTP (#035)
Ohne authentik gab es nur den Notfall-Admin – ein geteiltes Konto ohne
Rollen und ohne erkennbare Akteure im Audit-Log. Admins legen jetzt
lokale Konten an; sshkv erzeugt ein Einmal-Passwort, das bei der ersten
Anmeldung ersetzt wird, danach ist TOTP Pflicht.

Rollen, Sperren (beendet Sitzungen sofort) und Zurücksetzen unter
Einstellungen → Benutzer, nur für Admins mit frischer Bestätigung.
SSHKV_LOKALE_KONTEN=0 schaltet lokale Konten ab; der Notfall-Admin
bleibt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 22:36:25 +02:00
florian.wildeandClaude Opus 5.5 cab6f45510 feat(deploymentkey): geführte Rotation des Deployment-Keys (#031)
Bisher ließ sich der Instanz-Key nur von Hand auf jedem Host tauschen.
Die Rotation läuft jetzt in fünf Schritten: Nachfolger erzeugen, per
Dry-Run neben den alten verteilen, Anmeldung je Host prüfen, umstellen,
alten Key aus allen Blöcken entfernen und seinen Private Key verwerfen.

Der Nachfolger steht während der Rotation in Block und Pflichtliste,
damit kein Host ohne funktionierenden Key dasteht. Umgestellt wird nur
nach erfolgreicher Prüfung oder bewusstem Übergehen eines Hosts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:27:09 +02:00
florian.wildeandClaude Opus 5.5 ea6e44fced test(anmeldung): Namen gezielt im Benutzerkasten pruefen (#026)
Seit die Uebersicht echte letzte Aktionen zeigt, steht der Name des
Mock-Admins mehrfach auf der Seite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:08:06 +02:00
florian.wildeandClaude Opus 5.5 d9e218a6d3 docs(anleitung): Kapitel Einstellungen und Benachrichtigungen (#029)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:56:52 +02:00
florian.wilde ca05d6a58e Merge branch 'phase/029-handbuch'
# Conflicts:
#	src/worker/index.ts
2026-10-12 16:56:22 +02:00
florian.wilde b99d19ec8c Merge branch 'phase/028-benachrichtigungen'
# Conflicts:
#	docker-compose.yml
#	scripts/screenshots.ts
2026-10-12 16:55:57 +02:00
florian.wildeandClaude Opus 5.5 3e19b11a80 test(einstellungen): E2E, Screenshots und Issue-Abschluss (#028)
Der E2E-Lauf belegt im gebauten Stand, was die Unit- und DB-Tests nur
einzeln zeigen: ein Admin speichert SMTP, die Testnachricht kommt ueber
den Worker in Mailpit an, das Passwort kehrt nie in die Seite zurueck,
und ein Leser sieht keine Aendern-Knoepfe. Die Screenshots (1440/390 px)
halten das Layout der neuen Seite fuer die Anleitung fest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:54:56 +02:00
florian.wildeandClaude Opus 5.5 7721a9f764 docs(anleitung): Kapitel Audit-Log und Syslog-Variablen (#029)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:49:28 +02:00
florian.wilde 461cab1389 Merge branch 'main' into phase/029-handbuch 2026-10-12 16:49:27 +02:00
florian.wilde 2a45d4cc46 Merge branch 'phase/027-protokoll-ansicht' 2026-10-12 16:48:27 +02:00
florian.wildeandClaude Opus 5.5 0154343fd2 feat(protokoll): Audit-Log mit Filtern, Kettenpruefung und CSV (#027)
Das Protokoll war bisher nur in der Datenbank lesbar. Die Ansicht zeigt es
jeder Rolle mit lesbaren Aktionstexten, aufklappbarem Diff, Details und
Hashes; ein Test haelt fest, dass jede Aktion im Code einen Text hat.

Geblaettert wird ueber die ID statt OFFSET, weil das Protokoll waehrend
des Lesens waechst. Die Kettenpruefung liest jede Zeile und laeuft deshalb
nur auf Knopfdruck, mit 5 Minuten Zwischenspeicher; ein Bruch wird selbst
protokolliert. Der CSV-Export streamt in Stapeln, entschaerft Formeln und
steht selbst im Protokoll. protokollieren() reicht jeden Eintrag nach dem
Schreiben an Syslog weiter, ohne Details und Diff.

Kein Weg aendert oder loescht Eintraege; ein struktureller Test sichert
das ab, zusaetzlich zum Trigger.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:47:44 +02:00
florian.wildeandClaude Opus 5.5 3b28f73c95 docs(betrieb): Handbuch, Bedrohungsanalyse, geprobte Sicherung (#029)
Handbuch mit Bildern fuer alle Ablaeufe, darunter der Kern-
Anwendungsfall und der Deployment-Zugang fuer Claude Code.
Betriebsdoku zu Installation, authentik und Reverse Proxy sowie eine
Bedrohungsanalyse mit Notfallplan fuer den Fall, dass sshkv selbst
kompromittiert wird.

Sicherung und Wiederherstellung als Skripte, auf einem Wegwerf-Stapel
geprobt. Dabei fielen zwei Fehler auf: das Schema der Warteschlange
liess sich nicht zurueckspielen, und ein Abbruch ohne Transaktion
loeschte es halb. Jetzt nur Schema public, in einer Transaktion, mit
Pruefwert des Master-Keys. Der Worker startet nicht, wenn der
Master-Key nicht zur Datenbank passt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:46:38 +02:00
florian.wildeandClaude Opus 5.5 ca61ca5b41 feat(uebersicht): echte Zahlen statt Beispieldaten (#026)
Kennzahlen, Hosts mit Abweichung, bald ablaufende Schluessel und letzte
Aktionen kommen aus der Datenbank; die Beispieldaten des Prototyps sind
entfernt. Befunde werden je Host und Benutzer in fester Reihenfolge
zusammengefasst, abgelaufene und noch ausgerollte Schluessel stehen in
Koralle. Anmeldungen bleiben dem Audit-Log vorbehalten, sonst
verdraengten sie auf der Uebersicht alles andere.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:33:11 +02:00
florian.wildeandClaude Opus 5.5 18f72f9d03 chore(release): 0.4.0 - Phase 4 abgeschlossen
Abgleich und Drift-Erkennung, Import, Rotation, Widerruf und
Zuweisungsmatrix. CHANGELOG und DEVLOG nachgetragen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:40:32 +02:00
florian.wilde 6407a2815d Merge branch 'phase/023-024' (Rotation, Widerruf) 2026-10-12 13:31:47 +02:00
florian.wildeandClaude Opus 5.5 f6ed66fc7e feat(rotation): gefuehrte Rotation mit Test vor dem Widerruf (#023)
Einen Schlüssel zu tauschen soll keinen Ausfall riskieren: Der Nachfolger
übernimmt alle aktiven Zuweisungen, wird ausgerollt und per
Verbindungstest geprüft – erst wenn alle Tests seit dem letzten Ausrollen
grün sind, entfernt der Widerruf aus #024 den alten Schlüssel, der dann
als ROTIERT endet.

Private Keys bekommen einen neuen Pfad (-rJJJJMMTT) bei gleichem Alias.
Damit ssh den neuen nimmt, schreibt privat.ts je Alias nur noch einen
config-Eintrag; die jüngste Zuweisung gewinnt. Der Worker setzt
vorgaengerId schon beim Erzeugen, so ist die Kette auch nach einem
Abbruch vollständig und die Schrittfolge wiederaufnehmbar.

Personen-Keys ohne Private Key in sshkv bekommen nur einen Hinweis:
dafür braucht es einen neuen Public Key von der Person.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:30:39 +02:00
florian.wildeandClaude Opus 5.5 c6361ff3c6 feat(widerruf): Widerruf und Massenwiderruf mit Dry-Run (#024)
Ein Schlüssel soll nach Projektende mit einem Klick von allen Hosts
verschwinden – aber nie als „widerrufen“ gelten, solange er irgendwo noch
liegt. Deshalb ein Zwischenzustand (widerrufEingeleitetAm): Verwendungen
werden zum Entfernen vorgemerkt, der bestehende Dry-Run mit Hash-Sperre
zeigt und schreibt die Änderungen, und erst wenn keine Verwendung mehr
offen ist, setzt der Abschluss WIDERRUFEN (bzw. ROTIERT für #023).
Scheitert ein Host, bleibt der Schlüssel im Zwischenzustand und die Seite
nennt die offenen Ziele.

Zielkonten lassen sich optional mit entfernen, aber erst nach den
Schlüsseln und nie, wenn ein anderer aktiver Schlüssel sie noch nutzt.
Massenwiderruf (Admin, frische Bestätigung) nutzt einen gemeinsamen
Dry-Run und protokolliert je Schlüssel. Abgelaufene Schlüssel erscheinen
im Filter „abgelaufen“ und bieten den Widerruf an – entfernt wird nie
automatisch.

Migration 20261012130000_widerruf_eingeleitet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:14:01 +02:00
florian.wilde 34f5b1f6df Merge branch 'phase/025-zuweisungsmatrix' 2026-10-12 13:06:33 +02:00
florian.wildeandClaude Opus 5.5 cbeb0235f2 test(abgleich): Abgleich und Uebernahme im Browser (#021, #022)
Gebauter Stand mit Worker: fremder Key auf dem Testziel, Abgleich
zeigt ihn als unbekannt, Uebernahme in den Block mit Dry-Run, danach
keine offenen Abweichungen. Der Test raeumt einen Benutzer deploy aus
frueheren Laeufen weg - genau den hat der Abgleich zu Recht als von
Hand geaenderten Block gemeldet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:05:20 +02:00
florian.wildeandClaude Opus 5.5 a47cae4082 feat(zuweisungen): Matrix Schluessel x Host mit CSV-Export (#025)
Bisher liess sich nur je Schluessel oder je Host nachsehen, wo ein Key
verwaltet ist. Die Matrix zeigt das auf einen Blick, loest
Hostgruppen-Zuweisungen je Mitglied auf (P vs. P·G) und macht nicht
synchrone Zustaende ohne Farbe erkennbar.

Die Matrix plant nur: Zuweisen und Entfernen laufen ueber die
vorhandenen Aktionen, ausgerollt wird weiter per Dry-Run auf der
Schluesselseite. Der Aufbau ist eine reine Funktion in src/lib, damit
Seite und CSV-Export garantiert dasselbe zeigen und die
Gruppenaufloesung ohne Datenbank testbar ist. Der CSV-Export entschaerft
Formelbeginne, weil Schluesselnamen frei waehlbar sind und Excel sie
sonst ausfuehren wuerde.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 13:05:12 +02:00
florian.wildeandClaude Opus 5.5 2c658b1223 chore(release): 0.3.0 - Phase 3 abgeschlossen
Host-zu-Host-Assistent, Zielkonten mit sudoers, Vorlagen. CHANGELOG
und DEVLOG nachgetragen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:25:16 +02:00
florian.wilde 00cff56500 Merge branch 'phase/018-020-assistent' 2026-10-12 11:19:33 +02:00
florian.wildeandClaude Opus 5.5 b80f14c5d7 feat(assistent): Host-zu-Host-Assistent mit Vorlagen (#018, #020)
Ein Durchgang fuer den Kern-Anwendungsfall: Vorlage und Zweck, Host A,
Host B mit Zielbenutzer, Zusammenfassung, dann Schluessel erzeugen,
Benutzer anlegen, zuweisen, Dry-Run, ausrollen und Verbindung testen.
Die Vorlage Deployment-Zugang fuellt deploy, Ablaufdatum, from= und
Alias vor; bei root als Ziel warnt der Assistent ausdruecklich.

Die Ausfuehrung ist wiederaufnehmbar: wird mittendrin eine frische
Bestaetigung fuer das Zielkonto noetig, geschieht sie in einem neuen
Tab, und nichts wird doppelt angelegt. Zielkonten laufen als eigene
Vorgaenge (neue Migration) und merken sich, ob sshkv den Benutzer
angelegt hat - nur dann loescht ein Widerruf ihn spaeter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:19:28 +02:00
florian.wildeandClaude Opus 5.5 458f62289a test(vorlagen): Service-, E2E-Tests und Screenshots (#019)
Der Service war nur ueber die reinen Pruefregeln abgedeckt. Die
DB-Tests halten fest, was die Oberflaeche voraussetzt: doppelte Namen
melden sich am Feld name, Aenderungen protokollieren genau die
geaenderten Felder, eingebaute Vorlagen lassen sich nicht archivieren.
Der E2E-Ablauf prueft Feldfehler, Vorschau und Rechte im gebauten
Stand; die Screenshots dienen der Layout-Abnahme bei 390 px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:16:42 +02:00
florian.wildeandClaude Opus 5.5 12603eb145 feat(schluessel): Zuweisen und Ausrollen auf der Schluesselseite (#017)
Auf der Seite eines Schluessels: Public Key einem Host oder einer
Gruppe zuweisen, Private Key (nur Admin) auf einen Quell-Host legen -
mit ~/.ssh/config-Eintrag und dem Host-Key des Ziels in known_hosts -,
Dry-Run fuer alle Ziele, anwenden und die Verbindung von A nach B
testen. Der Kern-Anwendungsfall laeuft damit im Browser durch (E2E).

Der Dry-Run nimmt Private-Key-Ziele nur fuer Admins auf: sonst koennte
ein Operator einen vorbereiteten Private Key ausrollen lassen. Die
Vorschau zeigt je Datei die Aktion; der Inhalt eines Private Keys
erreicht den Browser nie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:05:03 +02:00
florian.wilde 445afe3a9b Merge branch 'phase/012-014' (Schluessel, Personen, Private Key)
# Conflicts:
#	src/components/vorgang/useVorgang.ts
#	src/worker/handler.ts
2026-10-12 10:54:09 +02:00
florian.wildeandClaude Opus 5.5 2b6f826ce0 docs(anleitung): Screenshots Schluessel, Personen, Self-Service (#014)
Neue Aufnahmen fuer Schluesselliste, Neuer Schluessel, Schluesseldetail
(echter Demo-Key statt Prototyp), Personen und Meine Schluessel; die
uebrigen neu, weil die Navigation jetzt "Meine Schluessel" zeigt.
Aufgenommen gegen den gebauten Stand mit SSHKV_SEED_DEMO=1, 390 px ohne
seitliches Scrollen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:51:17 +02:00
florian.wildeandClaude Opus 5.5 8056b8a0c9 test(ausrollen): Dry-Run und Ausrollen im Browser (#016)
Gebauter Stand mit Worker gegen das Testziel: Host einrichten, Dry-Run
zeigt das Diff, auf dem Host aendert sich noch nichts, nach dem
Anwenden steht der Key mit seinen Einschraenkungen im Block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:21:54 +02:00
florian.wildeandClaude Opus 5.5 4584669962 feat(hosts): Host-Key und Bootstrap in der Oberflaeche (#009, #010)
Auf der Hostseite: Host-Key abrufen, Fingerprint vergleichen und
vertrauen oder ablehnen. Weicht ein Key vom vertrauten ab, erscheint
eine deutliche Warnung, und Annehmen geht nur mit Haekchen und frischer
Bestaetigung. Danach Bootstrap per Einmal-Passwort oder per Befehl und
Verbindungspruefung, jeweils mit Fortschrittsanzeige.

Der sshd-Befund empfiehlt prohibit-password, wenn root sich per
Passwort anmelden darf - nur als Hinweis, geaendert wird nichts.

E2E im gebauten Stand mit Worker gegen ein echtes sshd.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:00:43 +02:00
florian.wildeandClaude Opus 5.5 c8a415f1ca chore(hosts): Demo-Daten, Screenshots und Issue-Notizen (#008)
SSHKV_SEED_DEMO=1 legt sechs Demo-Hosts, drei Gruppen und einen Kunden an,
damit Entwicklung, Screenshots und Handbuch ohne echte Server auskommen.
Nur mit der Variable, damit eine echte Instanz nie Phantom-Hosts bekommt;
Upsert nach Name haelt den Seed idempotent.

Das Screenshot-Skript kennt jetzt Seiten mit wechselnder ID (folgen: erster
passender Link) und nimmt Hostliste und Hostdetail auf.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:50:53 +02:00
florian.wildeandClaude Opus 5.5 d1ba822a4a feat(auth): Anmeldeseiten, TOTP-Einrichtung und Bestaetigung (#004)
Anmeldung, Einrichtung des zweiten Faktors fuer den Notfall-Admin,
erneute Bestaetigung vor kritischen Aktionen und die Seite fuer
fehlende Rechte. Die Huelle zeigt jetzt den echten Benutzer, und jede
Seite prueft die Sitzung selbst; ein struktureller Test haelt das fest.

Die Ablaeufe sind im gebauten Stand gegen den Mock-OIDC geprueft
(pnpm test:e2e): Admin, Konto ohne Gruppe, Notfall-Admin mit TOTP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:28:51 +02:00
florian.wildeandClaude Opus 5.5 4af07e9553 docs(anleitung): Screenshot-Skript und Bilder des Prototyps (#002)
scripts/screenshots.ts nimmt Uebersicht und Schluesseldetail bei
1440x900 und 390x844 auf und meldet nebenbei horizontalen Ueberlauf,
damit es fuer die Anleitung (#029) und als schneller Layout-Test taugt.
Issue #002 ist damit erledigt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:21:02 +02:00