#032 Nacharbeiten aus Phase 4/5 #32

Closed
opened 2026-10-12 15:13:29 +00:00 by florian.wilde · 0 comments
Owner

Ziel

Kleinere offene Punkte aus den Berichten der Phasen 4 und 5 erledigen.

Aufgaben

  • Massenwiderruf im Browser testen (E2E mit frischer Bestätigung über den Mock-OIDC)
  • Laufende Rotation abbrechen können (Nachfolger widerrufen, Vorgänger wieder aktiv)
  • Protokoll-IDs ohne Zweierschritte (Spalten-Default und Trigger ziehen beide nextval)
  • „Zum Dry-Run“ aus der Zuweisungsmatrix direkt zur Dry-Run-Karte springen (Anker)

Akzeptanzkriterien

  • Alle Suiten grün

Abhängigkeiten

#023, #024, #025, #027

Notizen / Entscheidungen

  • Massenwiderruf: Der neue E2E-Test (widerruf.spec.ts) fand einen echten Fehler: Die Seite
    /schluessel/widerruf filterte ?id= mit /^[a-z0-9]{1,64}$/. Vom Worker erzeugte Schlüssel tragen
    eine UUID mit Bindestrichen – jeder erzeugte Schlüssel fiel still heraus („Keine Schlüssel gewählt“).
    Jetzt idsAusSuchparameter in src/lib/schluessel.ts (mit Test). Außerdem nannte der Hinweis nach
    verweigerter Bestätigung den falschen Knopf („Widerruf vorbereiten“ statt „2 Schlüssel widerrufen“).
    datenbank() und oidcBestaetigen() liegen jetzt in tests/e2e/hilfen.ts.
  • Rotation abbrechen: kein neues Feld. Abbrechen = Widerruf des Nachfolgers über den Ablauf aus #024
    (Dry-Run, er kann schon ausgerollt sein); ein Nachfolger im Widerruf bzw. widerrufen ist die
    abgebrochene Rotation (rotationAbgebrochen). vorgaengerId bleibt für die Historie, der Abbruch
    steht als schluessel.rotation.abgebrochen im Protokoll – in derselben Transaktion wie das Vormerken
    (widerrufEinleiten nimmt dafür optional zusaetzlich an). Der alte Schlüssel bleibt unverändert; bei
    gleichem Alias zeigt die config nach dem Anwenden wieder auf die alte Datei (nur verbleibende
    Zuweisungen landen im Block).
  • Abbrechen geht nur, solange der alte Schlüssel noch nicht entfernt wird (Schritt 5) – sonst wären am
    Ende beide halb entfernt. Auf dem Nachfolger ersetzt „Rotation abbrechen“ den normalen
    „Widerrufen“-Knopf, damit der Abbruch immer im Protokoll steht.
  • widerrufAbschliessen setzt ROTIERT nur noch bei einem aktiven Nachfolger, der nicht selbst im
    Widerruf ist; die Seite schreibt „Ersetzt durch …“ nur bei ROTIERT.
  • Kein zweiter Nachfolger: vorgaengerId ist eindeutig (1:1-Relation). Nach einem Abbruch lässt sich
    derselbe Schlüssel deshalb nicht erneut über sshkv rotieren; Seite und Fehlermeldung sagen das
    (neuen Schlüssel anlegen, zuweisen, alten widerrufen). Eine erneute Rotation bräuchte eine
    1:n-Relation mit eindeutigem Teilindex „ein nicht widerrufener Nachfolger je Vorgänger“.
    → Behoben in #033 (partieller Index statt 1:1).
  • Protokoll-IDs: Migration 20261012173000_protokoll_id_lueckenlos setzt den Spalten-Default auf den
    Platzhalter 0 (Prisma: @default(0), create ohne ID geht weiter); die ID zieht nur noch der
    Trigger unter der Advisory-Sperre aus der weiterhin zugeordneten Sequenz. Bestehende Zeilen bleiben
    unverändert (die ID steckt in der Hash-Eingabe), alte Lücken bleiben also stehen. Eine mitgegebene ID
    überschreibt der Trigger weiterhin.
  • Anker: Die Dry-Run-Karte trägt id="dry-run" (Karte nimmt eine optionale id) und
    scroll-mt-20 wegen der festen Kopfleiste der schmalen Ansicht; „Zum Dry-Run“ zeigt auf
    /schluessel/<id>#dry-run.

Quelle: docs/issues/032-nacharbeiten.md – dort wird dieses Issue gepflegt.

## Ziel Kleinere offene Punkte aus den Berichten der Phasen 4 und 5 erledigen. ## Aufgaben - [x] Massenwiderruf im Browser testen (E2E mit frischer Bestätigung über den Mock-OIDC) - [x] Laufende Rotation abbrechen können (Nachfolger widerrufen, Vorgänger wieder aktiv) - [x] Protokoll-IDs ohne Zweierschritte (Spalten-Default und Trigger ziehen beide `nextval`) - [x] „Zum Dry-Run“ aus der Zuweisungsmatrix direkt zur Dry-Run-Karte springen (Anker) ## Akzeptanzkriterien - [x] Alle Suiten grün ## Abhängigkeiten #023, #024, #025, #027 ## Notizen / Entscheidungen - **Massenwiderruf:** Der neue E2E-Test (`widerruf.spec.ts`) fand einen echten Fehler: Die Seite `/schluessel/widerruf` filterte `?id=` mit `/^[a-z0-9]{1,64}$/`. Vom Worker erzeugte Schlüssel tragen eine UUID mit Bindestrichen – jeder erzeugte Schlüssel fiel still heraus („Keine Schlüssel gewählt“). Jetzt `idsAusSuchparameter` in `src/lib/schluessel.ts` (mit Test). Außerdem nannte der Hinweis nach verweigerter Bestätigung den falschen Knopf („Widerruf vorbereiten“ statt „2 Schlüssel widerrufen“). `datenbank()` und `oidcBestaetigen()` liegen jetzt in `tests/e2e/hilfen.ts`. - **Rotation abbrechen:** kein neues Feld. Abbrechen = Widerruf des Nachfolgers über den Ablauf aus #024 (Dry-Run, er kann schon ausgerollt sein); ein Nachfolger im Widerruf bzw. widerrufen *ist* die abgebrochene Rotation (`rotationAbgebrochen`). `vorgaengerId` bleibt für die Historie, der Abbruch steht als `schluessel.rotation.abgebrochen` im Protokoll – in derselben Transaktion wie das Vormerken (`widerrufEinleiten` nimmt dafür optional `zusaetzlich` an). Der alte Schlüssel bleibt unverändert; bei gleichem Alias zeigt die config nach dem Anwenden wieder auf die alte Datei (nur verbleibende Zuweisungen landen im Block). - Abbrechen geht nur, solange der alte Schlüssel noch nicht entfernt wird (Schritt 5) – sonst wären am Ende beide halb entfernt. Auf dem Nachfolger ersetzt „Rotation abbrechen“ den normalen „Widerrufen“-Knopf, damit der Abbruch immer im Protokoll steht. - `widerrufAbschliessen` setzt `ROTIERT` nur noch bei einem aktiven Nachfolger, der nicht selbst im Widerruf ist; die Seite schreibt „Ersetzt durch …“ nur bei `ROTIERT`. - **Kein zweiter Nachfolger:** `vorgaengerId` ist eindeutig (1:1-Relation). Nach einem Abbruch lässt sich derselbe Schlüssel deshalb nicht erneut über sshkv rotieren; Seite und Fehlermeldung sagen das (neuen Schlüssel anlegen, zuweisen, alten widerrufen). Eine erneute Rotation bräuchte eine 1:n-Relation mit eindeutigem Teilindex „ein nicht widerrufener Nachfolger je Vorgänger“. → Behoben in #033 (partieller Index statt 1:1). - **Protokoll-IDs:** Migration `20261012173000_protokoll_id_lueckenlos` setzt den Spalten-Default auf den Platzhalter `0` (Prisma: `@default(0)`, `create` ohne ID geht weiter); die ID zieht nur noch der Trigger unter der Advisory-Sperre aus der weiterhin zugeordneten Sequenz. Bestehende Zeilen bleiben unverändert (die ID steckt in der Hash-Eingabe), alte Lücken bleiben also stehen. Eine mitgegebene ID überschreibt der Trigger weiterhin. - **Anker:** Die Dry-Run-Karte trägt `id="dry-run"` (`Karte` nimmt eine optionale `id`) und `scroll-mt-20` wegen der festen Kopfleiste der schmalen Ansicht; „Zum Dry-Run“ zeigt auf `/schluessel/<id>#dry-run`. --- Quelle: `docs/issues/032-nacharbeiten.md` – dort wird dieses Issue gepflegt.
florian.wilde added this to the v1.0.0 milestone 2026-10-12 15:13:29 +00:00
florian.wilde added the testchore labels 2026-10-12 15:13:29 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: florian.wilde/sshkeyvault#32