Files
sshkeyvault/DEVLOG.md
T
florian.wildeandClaude Opus 5.5 0a58f6ce32 chore(release): 0.2.0 - Phase 2 abgeschlossen
Schluessel, Personen, Private Key anzeigen, authorized_keys-Parser und
Ausrollen von Public Keys; vorgezogen das Ausrollen von Private Keys
mit ssh-config und known_hosts. CHANGELOG und DEVLOG nachgetragen.

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

87 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DEVLOG – SSHKeyVault
## Zeitübersicht
**Gesamt (Wandzeit):** 2 h 25 min
**Summe der Issue-Zeiten:** 7 h 08 min – Sub-Agenten arbeiteten parallel an #002, #006, #008, #011 und #012–#014.
| Issue | Zeit |
|---|---|
| Planung (Phase 0) | 0 h 20 min |
| #001 Projekt-Setup | 0 h 15 min |
| #002 Design-System und Layout | 0 h 18 min |
| #003 Datenmodell und Migrationen | 0 h 10 min |
| #004 Anmeldung, Rollen und Bestätigung | 0 h 45 min |
| #005 Revisionssicheres Protokoll | 0 h 10 min |
| #006 Verschlüsselte Ablage und Schlüsselformat | 0 h 25 min |
| #007 Worker und Vorgänge | 0 h 15 min |
| #008 Hosts und Hostgruppen | 0 h 30 min |
| #009 Host-Key-Prüfung | 0 h 25 min |
| #010 Bootstrap | 0 h 35 min |
| #011 Test-SSH-Container | 0 h 15 min |
| #012 Schlüssel erzeugen, importieren, exportieren | 0 h 25 min |
| #013 Personen und Self-Service | 0 h 10 min |
| #014 Private Key anzeigen | 0 h 10 min |
| #015 authorized_keys-Parser | 0 h 15 min |
| #016 Public Key ausrollen | 0 h 40 min |
| #017 Private Key ausrollen | 0 h 45 min |
| #018 Zielbenutzer und sudoers (Teil) | 0 h 10 min |
| #019 Vorlagen (Teil) | 0 h 10 min |
| #020 Verbindungstest (Teil) | 0 h 05 min |
| Meilenstein | Zeit |
|---|---|
| v0.1.0 | 1 h 25 min (Wandzeit) | **abgeschlossen**
| v0.2.0 | 1 h 00 min (Wandzeit) | **abgeschlossen**
---
## 2026-10-12 · Sitzung 1 · 08:45–10:10
**Issue:** Planung, #001–#011
**Version:** 0.1.0
### Erledigt
- Auftrag gelesen, Architektur, Datenmodell, Sicherheitskonzept und Phasenplan entworfen (`docs/PLAN.md`)
- Sieben Rückfragen gestellt und beantwortet, Plan freigegeben
- Konventionen aus Laufzettel und ProxLedger übernommen; Git-Repository mit lokaler Identität angelegt
- 30 Issues für Phase 1–5 als Dateien angelegt (Gitea folgt mit #030)
- #001 Grundgerüst; #003 Datenmodell mit Datenbankregeln und Protokoll-Hash-Kette als Trigger
- #002, #006 (Kern), #011 parallel von Sub-Agenten in eigenen Worktrees, danach gemergt
- #004 Anmeldung: OIDC gegen Mock-Anbieter, Notfall-Admin mit TOTP, Re-Auth; E2E im gebauten Stand
- #005 Protokoll-Service mit Schwärzen; #006 Teil 2: Versiegeln im Worker, Deployment-Key
- #007 Worker mit pg-boss; vollständiger Docker-Stapel geprüft (migrate, web, worker gesund)
- #008 Hosts und Hostgruppen (Sub-Agent)
- #009 strikte Host-Key-Prüfung und TOFU, #010 Bootstrap – Integrationstests gegen echtes sshd, E2E im Browser bis zur Verbindungsprüfung
- Stand: 287 Unit-/DB-Tests, 17 Integrationstests, 5 E2E-Abläufe grün
### Entscheidungen
- **Kein Auth.js:** v5 steht dauerhaft auf Beta – wie in Laufzettel `openid-client` + `jose`.
- **Web und Worker getrennt, Master-Key nur im Worker:** Eine Lücke im Webprozess allein entschlüsselt keine Private Keys.
- **Schlüsselerzeugung ohne `ssh-keygen`:** Node `crypto` + eigener OpenSSH-Serializer, damit Private Keys nie als Datei auf dem sshkv-Server liegen. `ssh-keygen` prüft in den Tests die Kompatibilität.
- **Dienstbenutzer `sshkv` mit sudo als Standard,** `root` pro Host wählbar.
- **Ohne sshkv-Gruppe kein Zugang** – auch kein Lesezugriff.
- **Protokoll-Hash im Datenbank-Trigger:** Niemand kann eine Zeile ohne Verkettung einfügen; die ID wird erst unter Sperre vergeben, damit die Kette auch bei parallelem Schreiben hält.
- **Ein Bootstrap-Skript für Passwort- und Copy-Paste-Weg,** Dateizugriffe als Zielbenutzer (Symlink-Schutz).
- **Eigene Testdatenbank je parallelem Lauf:** Sub-Agent und Hauptsitzung leerten sich gegenseitig die Tabellen (in `CLAUDE.md` festgehalten).
- **Prisma-Client in den Worker gebündelt:** Im Standalone-Abbild fand die ESM-Auflösung `@prisma/client` sonst nicht (erst im echten Docker-Stapel aufgefallen).
- **Worker-Benutzer in Compose wählbar** (`SSHKV_WORKER_USER`), weil Docker-Secrets ohne Swarm die Rechte der Host-Datei tragen.
## 2026-10-12 · Sitzung 2 · 10:07–11:07
**Issue:** #012–#020
**Version:** 0.2.0
### Erledigt
- #012–#014 (Schlüssel, Personen/Self-Service, Private Key anzeigen) von einem Sub-Agenten in eigenem Worktree, danach gemergt; Konflikte in `useVorgang` und der Handler-Tabelle zusammengeführt
- #015 authorized_keys-Parser und Merge mit 26 Randfall-Tests
- #016 Public Keys ausrollen: Soll, Trockenlauf, Ausrollen, Hostseite, Schlüsselseite – Integrationstests und E2E
- #017 Private Key mit `~/.ssh/config` und `known_hosts` – Integrationstest „A meldet sich bei B an“, E2E für den ganzen Kern-Anwendungsfall
- Vorgezogen: #018 Zielkonto-Skripte (Integrationstests), #019 Vorlagen-Logik, #020 Verbindungstest
- Stand: 410 Unit-/DB-Tests, 30 Integrationstests, 12 E2E-Abläufe grün
### Entscheidungen
- **Phase 3 teilweise vorgezogen,** weil Florian „weiter“ sagte, während der Agent noch an Phase 2 arbeitete – nur Teile ohne Schemaänderung, damit die Migrationen des Agenten nicht kollidieren.
- **Trockenlauf und Ausrollen als zwei Vorgänge mit Hash-Sperre:** Es wird nie etwas anderes geschrieben, als jemand gesehen hat.
- **Private-Key-Ziele im Dry-Run nur für Admins:** Sonst hätte ein Operator einen vorbereiteten Private Key ausrollen lassen können (Freigabe Frage 3).
- **Keine Sicherungskopie alter Private Keys** auf dem Host; config-Block am Dateianfang, weil ssh den ersten Treffer nimmt.
- **Ein Hook `useVorgang` für alle:** zwei parallel entstandene Fassungen zusammengeführt, beide Schnittstellen bleiben.