Basis: Certvia dev@a48c5fb als Fundament für Craftvia
Unveränderter Stand von certvia/dev (a48c5fb) plus Craftvia-Spezifikation und Brandbook unter docs/craftvia/. ISMS-Module werden im Folgecommit entfernt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# Secrets-Register — restore-/betriebs-kritische Schlüssel (certvia)
|
||||
|
||||
> Produkt: **certvia** (ISMS-Tool). Umsetzung der Härtung §5 (`docs/KONZEPT-haertung.md`)
|
||||
> und Backup-Konzept §9 (`docs/KONZEPT-backup-restore.md`). **Ops-/Governance-Dokument, kein Code.**
|
||||
> Strikt getrennt von jedem anderen Produkt (insb. „visitvia") — eigene Secrets, eigener Tresor-Bereich.
|
||||
|
||||
Dieses Register ist die **einzige verbindliche Übersicht**, welche Secrets es gibt, wer sie besitzt,
|
||||
wie (und ob) sie rotiert werden und wo sie liegen. **Führung: ISB.** Ablageort der Werte:
|
||||
**Org-Passwortmanager** (je Umgebung getrennter Ordner) **+ versiegelte Offline-Kopie**.
|
||||
|
||||
## Grundregeln (gelten für ALLE Einträge)
|
||||
|
||||
1. **Je Umgebung getrennt** — `test` / `dev` / `prod` haben **eigene, unterschiedliche** Werte.
|
||||
Niemals einen prod-Wert in test/dev wiederverwenden (oder umgekehrt).
|
||||
2. **Nie im Artefakt-Bucket** — Secrets liegen **niemals** im selben Bucket/Speicher wie die
|
||||
verschlüsselten Backups oder DSGVO-Exporte. **Verlust des Keys = Verlust der Wiederherstellbarkeit.**
|
||||
3. **Nie im Repo / nie im Backup-Artefakt** — kein Secret ins Git, keins ins Backup-Payload.
|
||||
Verteilung nur als Coolify-Env-Secret + Passwortmanager.
|
||||
4. **Versiegelte Offline-Kopie** — pro Umgebung eine versiegelte Offline-Kopie (z. B. verschlossener
|
||||
Umschlag / getrennter Offline-Tresor) für den Totalausfall des Passwortmanagers.
|
||||
5. **Rotation protokollieren** — jede Rotation mit Datum, Auslöser und ausführender Person im
|
||||
Passwortmanager-Eintrag vermerken.
|
||||
|
||||
## Register
|
||||
|
||||
| Secret | Zweck | Eigentümer (Owner) | Rotierbar? | Rotationsregel je Umgebung |
|
||||
|---|---|---|---|---|
|
||||
| `AUTH_SECRET` | Session-/JWT-Signatur (Auth.js) | ISB / Betrieb | **Ja** | Rotation invalidiert alle aktiven Sessions (Nutzer müssen neu einloggen). Bei Verdacht auf Kompromittierung sofort, sonst periodisch (z. B. jährlich). Je Umgebung eigener Wert. |
|
||||
| `MFA_ENC_KEY` | Verschlüsselung der TOTP-Secrets at-rest (AES-256-GCM) | ISB | **NEIN**¹ | **Nicht rotierbar ohne MFA-Neueinrichtung.** „Rotation" = Reset: alle Nutzer müssen MFA neu einrichten (alte TOTP-Secrets werden unlesbar). Nur bei Kompromittierung mit geplantem Reset. |
|
||||
| `PASSWORD_PEPPER` | Passwort-Pepper (Argon2-`secret`, Phase 1) | ISB | **NEIN**¹ | **Nicht rotierbar ohne Passwort-Reset für alle** (kein Rehash-on-Login). „Rotation" = Reset: erzwungener Passwort-Neusatz aller Konten. Bewusst **einmalig** gesetzt (leere DBs). |
|
||||
| `BACKUP_ENC_KEY` | Client-seitige Verschlüsselung des App-Backup-Exports (AES-256-GCM); Fallback `AUTH_SECRET` | ISB / Betrieb | **Bedingt**² | Neuer Key gilt nur für **neue** Artefakte; alte Backups bleiben nur mit dem **alten** Key entschlüsselbar → Altschlüssel bis Ablauf der Retention **aufbewahren**. Je Umgebung eigener Wert. |
|
||||
| pgBackRest-Repo-Key (`repo-cipher-pass`) | AES-256-Verschlüsselung des Cluster-Backup-Repos (Postgres WAL/Base) | Betrieb | **Ja**³ | Rotierbar mit Repo-Rekey; alte Repos/Artefakte brauchen den Altschlüssel → bis Retention-Ende aufbewahren. Je Umgebung eigenes Repo + eigener Key. |
|
||||
| `age`-Keypair | Verschlüsselung Per-Tenant-Export + DSGVO-Pakete (X25519) | ISB / DSB | **Ja**³ | Neuer Recipient gilt für **neue** Artefakte; Private Key der Alt-Keys bis Retention-Ende aufbewahren (sonst Alt-Exporte nicht entschlüsselbar). Je Umgebung eigenes Keypair. |
|
||||
| restic-Repo-Passwort | Verschlüsselung des MinIO-Objekt-Backups (restic, AES-256) | Betrieb | **Ja**³ | Rotierbar (`restic key add/remove`); Altschlüssel bis Retention-Ende gültig halten. Je Umgebung eigenes Repo + eigenes Passwort. |
|
||||
|
||||
¹ **Nicht-rotierbar markiert:** `PASSWORD_PEPPER` und `MFA_ENC_KEY` sind **keine** rotierbaren
|
||||
Secrets im üblichen Sinn — eine „Rotation" bedeutet einen **Reset/Neuverschlüsselung** mit
|
||||
Benutzer-Impact (Passwort- bzw. MFA-Neueinrichtung für alle). Deshalb **bewusst einmalig** setzen
|
||||
(solange DBs leer/frisch) und wie einen Wiederherstellungsschlüssel behandeln.
|
||||
|
||||
² `BACKUP_ENC_KEY` ist technisch tauschbar, aber jeder alte Backup-Stand bleibt an seinen
|
||||
Erzeugungs-Key gebunden → nicht „rotieren und alten Key wegwerfen".
|
||||
|
||||
³ Backup-Keys (pgBackRest / `age` / restic) sind rotierbar, aber **Altschlüssel müssen bis zum
|
||||
Ende der jeweiligen Retention aufbewahrt** werden, sonst werden ältere Backups unwiederherstellbar.
|
||||
|
||||
## ⚠ Restore-Kohärenz (verbindliche Vorbedingung)
|
||||
|
||||
**`PASSWORD_PEPPER`, `MFA_ENC_KEY` und `BACKUP_ENC_KEY` sind Umgebungs-Secrets und stehen NICHT
|
||||
im Backup-Artefakt.** Ein Restore in eine Umgebung mit **anderen** Secrets bricht:
|
||||
|
||||
- **anderer `PASSWORD_PEPPER`** → **alle** Passwort-Prüfungen schlagen fehl (kein Login möglich).
|
||||
- **anderes `MFA_ENC_KEY`** → TOTP-Secrets nicht entschlüsselbar → MFA-Prüfung bricht.
|
||||
- **anderes `BACKUP_ENC_KEY`** → das AES-256-GCM-Backup-Artefakt lässt sich **gar nicht** entschlüsseln.
|
||||
|
||||
**Vorbedingung vor jedem Restore** (auch im Restore-Runbook `docs/DEPLOY-PROD-CONTABO.md` verankert):
|
||||
Die Zielumgebung hält **exakt die Secrets, mit denen das Backup erzeugt wurde** — oder es wird
|
||||
ein **Passwort-/MFA-Reset bzw. eine Neuverschlüsselung eingeplant**. Ein Cross-Environment-Restore
|
||||
(z. B. prod → staging zum Debuggen) läuft nur mit den **prod-Secrets** oder mit anschließendem Reset.
|
||||
|
||||
## Ablage & Zugriff (Runbook-Kurzform)
|
||||
|
||||
- **Primär:** Org-Passwortmanager, je Umgebung getrennter Ordner, Zugriff rollenbasiert (ISB + Betrieb).
|
||||
- **Sekundär:** versiegelte Offline-Kopie je Umgebung (Notfall/DR).
|
||||
- **Verteilung an die App:** ausschließlich als Coolify-Env-Secret (Runtime), nie ins Repo/Image.
|
||||
- **Host-Encryption-Passphrase** (LUKS-Volume, s. `docs/DEPLOY-PROD-CONTABO.md`): ebenfalls hier
|
||||
führen — dieselben Grundregeln (getrennt je Umgebung, offline versiegelt, nie im Backup-Bucket).
|
||||
- **Bei Personalwechsel:** rotierbare Secrets (`AUTH_SECRET`, Backup-Keys) neu setzen; Zugriff im
|
||||
Passwortmanager entziehen. Nicht-rotierbare (`PASSWORD_PEPPER`/`MFA_ENC_KEY`) nur bei begründetem
|
||||
Kompromittierungsverdacht — dann mit geplantem Reset.
|
||||
|
||||
## Bezug / Weiterführendes
|
||||
|
||||
- `docs/KONZEPT-haertung.md` §5 (Register-Anforderung), §1–§3 (Pepper, Host-Encryption, Backups).
|
||||
- `docs/KONZEPT-backup-restore.md` §9 (gemeinsames Verschlüsselungs-Primitiv, Schlüsselverwaltung).
|
||||
- `docs/DEPLOY-PROD-CONTABO.md` (Host-Encryption + verschlüsselte Backups + Restore-Kohärenz, Ops-Runbook).
|
||||
- **Phase 2 (offen):** Upgrade-Pfad auf **HashiCorp Vault** / Provider-**KMS** (Rotation, Audit,
|
||||
Trennung) sowie **DB-Connection-TLS** (`sslmode`) — bewusst zurückgestellt, nicht Teil dieser Lane.
|
||||
Reference in New Issue
Block a user