Spalten-Default (BIGSERIAL) und Trigger protokoll_verketten zogen je eine Nummer aus der Sequenz, jede Zeile verbrauchte zwei IDs. Die Nummer aus dem Default darf der Trigger aber nicht einfach uebernehmen, denn sie wird vor der Advisory-Sperre gezogen: Eine parallele Transaktion mit groesserer ID koennte zuerst verketten, und die Kette liesse sich in ID-Reihenfolge nicht mehr pruefen. Deshalb zieht nur noch der Trigger unter der Sperre; der Default ist ein Platzhalter 0 (Prisma: @default(0)), damit create ohne ID funktioniert. Die Sequenz bleibt der Spalte zugeordnet. Bestehende Zeilen werden nicht umnummeriert, weil die ID in die Hash-Eingabe eingeht. Tests: drei Eintraege nacheinander ergeben n, n+1, n+2; eine mitgegebene ID wird ueberschrieben; 20 parallele Eintraege belegen genau 20 aufeinanderfolgende IDs bei intakter Kette. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.5.0: alle fünf Phasen aus
docs/PLAN.mdumgesetzt – Hosts mit Host-Key-Prüfung und Bootstrap, Schlüssel, Ausrollen von Public und Private Keys mit Dry-Run, Host-zu-Host-Assistent, Abgleich, Rotation, Widerruf, Zuweisungsmatrix, Audit-Log, Benachrichtigungen. 1.0.0 nach der Abnahme.
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/betrieb/sicherheit.md (mit Bedrohungsanalyse und
Notfallplan) und docs/betrieb/sicherung.md.
Dokumentation
- Handbuch – Bedienung Schritt für Schritt mit Bildern
- Installation und Betrieb – Docker Compose, authentik, Reverse Proxy
- Sicherung und Wiederherstellung –
deploy/sichern.sh,deploy/wiederherstellen.sh - Sicherheit – Aufbau, Bedrohungsanalyse, Notfallplan
Installation (Docker Compose)
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
- Hosts → + Host anlegen (Name, Adresse, Port; Anmeldung als Dienstbenutzer
sshkvmit sudo – empfohlen – oder direkt als root). - Host-Key abrufen, den Fingerprint am Host vergleichen
(
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub) und vertrauen. - 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.
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