Merge branch 'phase/023-024' (Rotation, Widerruf)
This commit is contained in:
@@ -1,19 +1,46 @@
|
||||
# #023 Geführte Rotation
|
||||
**Status:** offen
|
||||
**Status:** erledigt
|
||||
**Meilenstein:** v0.4.0
|
||||
**Labels:** backend, ui
|
||||
**Geschätzt:** 3 h **Tatsächlich:** –
|
||||
**Geschätzt:** 3 h **Tatsächlich:** 0 h 20 min
|
||||
|
||||
## Ziel
|
||||
Neuer Schlüssel an allen Verwendungen, Test, alter entfernt.
|
||||
|
||||
## Aufgaben
|
||||
- [ ] wird zu Beginn der Phase verfeinert
|
||||
- [x] „Rotieren“ auf der Schlüsselseite, Schrittfolge `/schluessel/[id]/rotieren` (wiederaufnehmbar)
|
||||
- [x] Neuer Schlüssel gleichen Typs, Name „… (rotiert TT.MM.JJJJ)“, `vorgaengerId` = alter
|
||||
- [x] Zuweisungen übernehmen: Public gleiche Ziele/Optionen, Private gleicher Host/Benutzer/Alias mit neuem Pfad
|
||||
- [x] Dry-Run + Ausrollen, Verbindungstests, erst dann den alten widerrufen (#024) → `ROTIERT`
|
||||
- [x] Personen-Key ohne Private Key: nur Hinweis „neuer Public Key nötig“
|
||||
- [x] Rotationskette auf der Schlüsselseite (Vorgänger/Nachfolger verlinkt)
|
||||
|
||||
## Akzeptanzkriterien
|
||||
- [ ] wird zu Beginn der Phase verfeinert
|
||||
- [x] DB-Tests: Schritte, Reihenfolge, Rechte, Namen/Pfade (`tests/rotation.test.ts`)
|
||||
- [x] Integrationstest: neuer Schlüssel funktioniert, alter von beiden Hosts weg, `ssh <alias>` geht weiter
|
||||
- [x] E2E im Browser (`tests/e2e/rotation.spec.ts`), Screenshot `rotation-desktop.png`
|
||||
|
||||
## Abhängigkeiten
|
||||
#020
|
||||
#020, #024
|
||||
|
||||
## Notizen / Entscheidungen
|
||||
- **Fünf Schritte:** Neuer Schlüssel → Zuweisungen übernehmen → Dry-Run & Ausrollen → Verbindungstests →
|
||||
Alten widerrufen. Der aktuelle Schritt wird aus der Datenbank errechnet (`rotationsStand`), deshalb
|
||||
lässt sich die Rotation jederzeit neu laden und fortsetzen; jeder Schritt ist idempotent.
|
||||
- **Kette sofort:** Der Worker setzt `vorgaengerId` schon beim Erzeugen (neues Feld in der
|
||||
Vorgangs-Eingabe) – auch ein abgebrochener Browser hinterlässt keinen verwaisten Schlüssel.
|
||||
`vorgaengerId` ist eindeutig: zwei gleichzeitige Rotationen scheitern verständlich.
|
||||
- **Gleicher Alias, zwei Zuweisungen:** `privat.ts` schreibt je Alias genau einen config-Eintrag, die
|
||||
jüngste Zuweisung gewinnt (an der Position der ersten). So zeigt `ssh <alias>` nach dem Ausrollen auf
|
||||
die neue Datei, während die alte bis zum Widerruf daneben liegt.
|
||||
- **Neuer Pfad:** `<alter Pfad ohne -rJJJJMMTT>-rJJJJMMTT`, bei Kollision mit laufender Nummer –
|
||||
auch entfernte Zuweisungen belegen einen Pfad (eindeutiger Index über alle Zustände).
|
||||
- **Grün heißt aktuell:** Der alte Schlüssel wird nur widerrufen, wenn für jede Private-Zuweisung mit
|
||||
Alias ein erfolgreicher `VERBINDUNGSTEST` nach dem letzten Ausrollen vorliegt (Server prüft das).
|
||||
Ohne Private-Zuweisung mit Alias entfällt der Test.
|
||||
- **Abschluss:** Widerruf aus #024 ohne Zielkonten (der Nachfolger nutzt sie weiter); ein aktiver
|
||||
Nachfolger macht aus `WIDERRUFEN` den Status `ROTIERT`.
|
||||
- Ablaufdatum: Der Nachfolger erbt es nur, wenn es in der Zukunft liegt. Eine Passphrase wird nicht
|
||||
übernommen (sshkv erzeugt ohne).
|
||||
- Rechte: `schluesselVerwalten` + `publicKeyAusrollen`, bei Private-Zuweisungen `privateKeyAusrollen`.
|
||||
Deployment-Key: eigene Rotation (später).
|
||||
|
||||
@@ -1,19 +1,49 @@
|
||||
# #024 Widerruf und Massenwiderruf
|
||||
**Status:** offen
|
||||
**Status:** erledigt
|
||||
**Meilenstein:** v0.4.0
|
||||
**Labels:** backend, ui, sicherheit
|
||||
**Geschätzt:** 3 h **Tatsächlich:** –
|
||||
**Geschätzt:** 3 h **Tatsächlich:** 0 h 25 min
|
||||
|
||||
## Ziel
|
||||
Ein-Klick-Widerruf inkl. Benutzer/sudoers; Massenwiderruf mit Re-Auth.
|
||||
|
||||
## Aufgaben
|
||||
- [ ] wird zu Beginn der Phase verfeinert
|
||||
- [x] „Widerrufen“ auf der Schlüsselseite mit Dialog, der jede Entfernung auflistet
|
||||
- [x] Public- und Private-Verwendungen → ENTFERNEN, Dry-Run, anwenden, erst dann `WIDERRUFEN`
|
||||
- [x] Zielkonten optional entfernen (nur `vonSshkvAngelegt`, nie ein noch genutztes)
|
||||
- [x] Massenwiderruf auf der Schlüsselliste, ein gemeinsamer Dry-Run, Protokoll je Schlüssel
|
||||
- [x] Abgelaufene Schlüssel erkennbar (Filter) und Widerruf anbieten – ohne automatisches Entfernen
|
||||
|
||||
## Akzeptanzkriterien
|
||||
- [ ] wird zu Beginn der Phase verfeinert
|
||||
- [x] DB-Tests: Zustände, Rechte, Zielkonten, Protokoll ohne Geheimnisse (`tests/widerruf.test.ts`)
|
||||
- [x] Integrationstest gegen zwei Hosts inkl. „Host nicht erreichbar“ (`tests/integration/widerruf.test.ts`)
|
||||
- [x] E2E im Browser (`tests/e2e/widerruf.spec.ts`), Screenshot `widerruf-desktop.png`
|
||||
|
||||
## Abhängigkeiten
|
||||
#018
|
||||
|
||||
## Notizen / Entscheidungen
|
||||
- **Zwischenzustand statt Sofort-Status:** neues Feld `Schluessel.widerrufEingeleitetAm` (Migration
|
||||
`20261012130000_widerruf_eingeleitet`). Der Status bleibt AKTIV/ABGELAUFEN, bis keine Verwendung mehr
|
||||
offen ist; erst `widerrufAbschliessen` setzt `WIDERRUFEN` (bzw. `ROTIERT`, wenn ein aktiver Nachfolger
|
||||
existiert, #023). Schlüsselseite und Liste zeigen „Widerruf unvollständig“ und die offenen Ziele.
|
||||
- **Reihenfolge:** vormerken → Dry-Run/Anwenden (bestehende Hash-Sperre aus #016/#017) → optional
|
||||
Zielkonten (`ZIELKONTO_ENTFERNEN`, erst wenn die Schlüssel überall weg sind) → abschließen.
|
||||
Ein Ziel, das im Dry-Run scheitert (nicht erreichbar), wird nicht angewendet; seine Verwendung bleibt
|
||||
ENTFERNEN, ein neuer Dry-Run versucht es erneut. Der Abschluss läuft nach erfolgreichem Anwenden
|
||||
automatisch und meldet, was noch fehlt.
|
||||
- **Nichts zu schreiben:** Steht der Schlüssel schon nirgends mehr, bietet das Dry-Run-Panel
|
||||
„Zustand übernehmen“ an (sonst bliebe der Widerruf hängen).
|
||||
- **Archivierte Hosts:** sshkv verbindet sich dort nicht mehr – deren Verwendungen gelten sofort als
|
||||
entfernt; der Dialog sagt das, das Protokoll nennt die Hosts.
|
||||
- **Zielkonten:** Ein Zielkonto kennt seinen Schlüssel nicht; Kandidat ist ein von sshkv angelegtes Konto
|
||||
auf (Host, Benutzer) einer Zuweisung der widerrufenen Schlüssel. Nutzt ein anderer, nicht im Widerruf
|
||||
befindlicher Schlüssel das Konto noch, bleibt es (Dialog nennt den Schlüssel).
|
||||
- **Rechte:** nur Public Keys → `publicKeyAusrollen`; Private Keys → `privateKeyAusrollen` (Admin);
|
||||
mehrere Schlüssel → `massenwiderruf`, Zielkonten → `zielkontenVerwalten` (jeweils Admin mit frischer
|
||||
Bestätigung). Der Deployment-Key ist nicht widerrufbar. Ein Schlüssel im Widerruf lässt sich nicht
|
||||
mehr zuweisen.
|
||||
- **Ablauf:** Status-Filter „abgelaufen“ umfasst aktive Schlüssel mit vergangenem Ablaufdatum; die
|
||||
Schlüsselseite bietet dann „Jetzt widerrufen“. Entfernt wird nie automatisch.
|
||||
- Massenwiderruf als GET-Formular `/schluessel/widerruf?id=…` – die Auswahl der Zielkonten reist als
|
||||
`?zielkonten=` mit und übersteht Neuladen und erneute Bestätigung.
|
||||
|
||||
Reference in New Issue
Block a user