chore(release): 0.1.0 - Phase 1 abgeschlossen
Grundgeruest, Anmeldung, Hosts mit Host-Key-Pruefung und Bootstrap. README mit Installation und Ablauf fuer neue Hosts, CHANGELOG und DEVLOG nachgetragen. Offen im Meilenstein bleibt nur #030 (Gitea), das auf die Zugangsdaten wartet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+30
-2
@@ -8,5 +8,33 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
|
||||
## [Unveröffentlicht]
|
||||
|
||||
### Hinzugefügt
|
||||
- Projektplan mit Architektur, Datenmodell, Sicherheitskonzept und Phasenplan (`docs/PLAN.md`)
|
||||
- Issues für alle fünf Phasen in `docs/issues/`
|
||||
|
||||
### Geändert
|
||||
|
||||
### Behoben
|
||||
|
||||
### Sicherheit
|
||||
|
||||
## [0.1.0] – 2026-10-12
|
||||
|
||||
Phase 1: Grundgerüst, Anmeldung, Hosts und Bootstrap.
|
||||
|
||||
### Hinzugefügt
|
||||
- Projektplan mit Architektur, Datenmodell, Sicherheitskonzept und Phasenplan (`docs/PLAN.md`), Issues für alle fünf Phasen
|
||||
- Projektgerüst: Next.js 16, Prisma 7, PostgreSQL 17, pnpm, ESLint/Prettier/Vitest/Playwright, commitlint (#001)
|
||||
- Design „Tresor“: Design-Tokens, selbst gehostete Schriften, Logo, Favicon und PWA-Icons, Seitenleiste, Grundkomponenten (#002)
|
||||
- Datenmodell für alle Phasen mit Datenbankregeln (CHECK, partielle Indizes, Trigger) und Seed mit Notfall-Admin und eingebauten Vorlagen „Deployment-Zugang“, „Backup-Zugang“, „Admin-Zugang Person“ (#003)
|
||||
- Anmeldung per OIDC (authentik) mit Rollen Admin/Operator/Leser aus Gruppen; Notfall-Admin mit Passwort und Pflicht-TOTP; erneute Bestätigung vor kritischen Aktionen (#004)
|
||||
- Revisionssicheres Protokoll: append-only, Hash-Kette, Prüffunktion (#005)
|
||||
- OpenSSH-Schlüssel (ed25519, RSA-4096) erzeugen, lesen und schreiben ohne `ssh-keygen`, kompatibel geprüft; Envelope Encryption mit Master-Key; Deployment-Key der Instanz (#006)
|
||||
- Worker mit pg-boss und Vorgängen mit Fortschrittsanzeige; Dockerfile und Docker Compose für den Betrieb (#007)
|
||||
- Hosts und Hostgruppen anlegen, bearbeiten, archivieren, filtern; Demo-Daten mit `SSHKV_SEED_DEMO=1` (#008)
|
||||
- Host-Key-Prüfung nach TOFU: abrufen, Fingerprint bestätigen oder ablehnen, strikte Prüfung bei jeder Verbindung, Warnung bei Änderung (#009)
|
||||
- Bootstrap neuer Hosts per Einmal-Passwort oder Befehl zum Kopieren, mit Dienstbenutzer `sshkv` und sudoers; sshd-Hinweise (#010)
|
||||
- SSH-Testziele (Debian 13) und Mock-OIDC für Integrations- und E2E-Tests (#011)
|
||||
|
||||
### Sicherheit
|
||||
- Private Keys nur verschlüsselt in der Datenbank; nur der Worker kann sie öffnen – strukturell getestet
|
||||
- Ein `pg_dump` enthält keinen Klartext-Schlüssel (Test)
|
||||
- Bootstrap-Passwort wird nirgends gespeichert (Test); Dateien im Home des Zielbenutzers werden als dieser Benutzer geschrieben (Symlink-Test gegen `/etc/shadow`)
|
||||
- Content-Security-Policy mit Nonce, Sicherheits-Kopfzeilen, Rate-Limit für den Notfallzugang
|
||||
|
||||
@@ -2,29 +2,56 @@
|
||||
|
||||
## Zeitübersicht
|
||||
|
||||
**Gesamt:** 0 h 25 min
|
||||
**Gesamt (Wandzeit):** 1 h 25 min
|
||||
**Summe der Issue-Zeiten:** 4 h 23 min – Sub-Agenten arbeiteten parallel an #002, #006, #008 und #011.
|
||||
|
||||
| Issue | Zeit |
|
||||
|---|---|
|
||||
| Planung (Phase 0) | 0 h 25 min |
|
||||
| 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 |
|
||||
|
||||
| Meilenstein | Zeit |
|
||||
|---|---|
|
||||
| v0.1.0 | 1 h 25 min (Wandzeit) | **abgeschlossen**
|
||||
|
||||
---
|
||||
|
||||
## 2026-10-12 · Sitzung 1 · 08:45–laufend
|
||||
**Issue:** Planung, #001 ff.
|
||||
**Version:** 0.0.0
|
||||
## 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: Im auth.log der Hosts ist eindeutig zu sehen, was von sshkv kam, und root-Login kann ganz aus bleiben.
|
||||
- **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.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
# SSHKeyVault (`sshkv`)
|
||||
|
||||
Selbst gehostete Weboberfläche zur zentralen Verwaltung von SSH-Schlüsseln: Schlüsselpaare
|
||||
erzeugen und verwalten, Public Keys in `authorized_keys` verteilen, Private Keys gezielt auf
|
||||
andere Hosts ausrollen, Ist- und Soll-Zustand abgleichen – alles revisionssicher protokolliert.
|
||||
|
||||
> **Stand 0.1.0 (Phase 1):** Grundgerüst, Anmeldung (OIDC + Notfall-Admin mit TOTP), Hosts und
|
||||
> Hostgruppen, Host-Key-Prüfung (TOFU) und Bootstrap neuer Hosts. Schlüsselverwaltung und
|
||||
> Ausrollen folgen in Phase 2 und 3 – siehe [`docs/PLAN.md`](docs/PLAN.md).
|
||||
|
||||
## Sicherheit vorab
|
||||
|
||||
SSHKeyVault hat **root-Zugriff auf alle verwalteten Hosts**. Deshalb:
|
||||
|
||||
- nur im internen Netz bzw. VPN betreiben, mit Reverse Proxy und TLS davor;
|
||||
- den **Master-Key** (`SSHKV_MASTER_KEY_FILE`) getrennt von der Datenbank sichern – ohne ihn
|
||||
ist ein Datenbank-Backup wertlos, und mit ihm zusammen gibt es alle Private Keys preis;
|
||||
- Private Keys liegen nur verschlüsselt in der Datenbank (AES-256-GCM, Envelope Encryption);
|
||||
entschlüsseln kann ausschließlich der Worker, der Webprozess hat den Master-Key nicht.
|
||||
|
||||
Mehr dazu in [`docs/PLAN.md`](docs/PLAN.md), Abschnitt 3.
|
||||
|
||||
## Installation (Docker Compose)
|
||||
|
||||
```bash
|
||||
cp .env.example .env # Werte eintragen, siehe Kommentare
|
||||
openssl rand -base64 48 # → SSHKV_APP_SECRET
|
||||
mkdir -p geheim && head -c 32 /dev/urandom > geheim/master.key
|
||||
sudo chown 1001:1001 geheim/master.key && sudo chmod 400 geheim/master.key
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Die Oberfläche lauscht auf `127.0.0.1:3400` (`SSHKV_BIND`, `SSHKV_PORT`). Beim ersten Start legt
|
||||
der Dienst `migrate` das Schema, den Notfall-Admin (`SSHKV_BREAKGLASS_*`) und die eingebauten
|
||||
Vorlagen an; der Worker erzeugt den Deployment-Key der Instanz.
|
||||
|
||||
**Anmeldung:** über authentik (`SSHKV_OIDC_*`, Rollen über die Gruppen `sshkv-admins`,
|
||||
`sshkv-operators`, `sshkv-readers`). Der Notfall-Admin richtet bei der ersten Anmeldung TOTP ein.
|
||||
|
||||
## Einen Host aufnehmen
|
||||
|
||||
1. **Hosts → + Host anlegen** (Name, Adresse, Port; Anmeldung als Dienstbenutzer `sshkv` mit sudo
|
||||
– empfohlen – oder direkt als root).
|
||||
2. **Host-Key abrufen**, den Fingerprint am Host vergleichen
|
||||
(`ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub`) und vertrauen.
|
||||
3. **Bootstrap:** einmalig per Passwort (wird nicht gespeichert) oder den angezeigten Befehl auf
|
||||
dem Host einfügen und „Einrichtung prüfen“.
|
||||
|
||||
## Entwicklung
|
||||
|
||||
Node 24, pnpm 12, Docker. Konventionen und Befehle: [`CLAUDE.md`](CLAUDE.md).
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm db:up && pnpm db:migrate && pnpm db:seed
|
||||
pnpm test:ziele:up # SSH-Testziele + Mock-OIDC
|
||||
pnpm build && pnpm start # http://localhost:3400
|
||||
pnpm worker # zweites Terminal
|
||||
pnpm test && pnpm test:integration && pnpm test:e2e
|
||||
```
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "sshkv",
|
||||
"version": "0.0.0",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "SSHKeyVault – zentrale Verwaltung von SSH-Schluesseln mit Weboberflaeche",
|
||||
|
||||
Reference in New Issue
Block a user