From 0ae6b13d6ca6d7ae1fcb8830876a94a0dfafd566 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Wed, 19 Aug 2026 19:29:34 +0200 Subject: [PATCH] Audit-Siegel: Schluessel erreicht jetzt tatsaechlich den Container Ohne diesen Fix waere das Siegel im Docker-Betrieb wirkungslos geblieben - die Variable wurde nirgends an den Container durchgereicht. docker-compose.yml listet die Umgebungsvariablen einzeln auf und speist sie aus der .env im Projektstamm; ein env_file gibt es nicht, backend/.env wird vom Container also gar nicht gelesen. Dokumentiert und ergaenzt hatte ich bisher nur backend/.env.example - also die Datei, die fuer den Container irrelevant ist. - AUDIT_HMAC_KEY und AUDIT_HMAC_KEY_OLD in docker-compose.yml und in docker/docker-compose.yml aufgenommen (beide mit :- Default, damit ohne Wert weiterhin fail-safe ungesiegelt geschrieben wird) - beide Variablen samt Erklaerung in die .env.example im Projektstamm und in docker/.env.example uebernommen - README benennt jetzt explizit, welche Datei fuer welchen Betrieb gilt (Stamm-.env bei Docker, backend/.env nur ohne Container) Verifiziert: `docker-compose config` loest AUDIT_HMAC_KEY korrekt auf. Co-Authored-By: Claude Opus 5 --- .env.example | 28 ++++++++++++++++++++++++++++ README.md | 17 ++++++++++++++--- docker-compose.yml | 6 ++++++ docker/.env.example | 11 +++++++++++ docker/docker-compose.yml | 3 +++ 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 0ae3ae96..1e6f6432 100644 --- a/.env.example +++ b/.env.example @@ -53,6 +53,34 @@ JWT_REFRESH_EXPIRES_IN=7d # Generieren: openssl rand -hex 32 ENCRYPTION_KEY=change-this-to-64-hex-characters-please-rotate-before-production-xx +# ---------- Siegel für das Audit-Log ---------- +# OpenCRM protokolliert, wer wann welche Daten gesehen oder geändert hat – die +# Beweisspur bei Streit oder Datenschutz-Nachfragen. Dieser Schlüssel versieht +# jeden neuen Eintrag mit einem Siegel, das sich nur damit erzeugen lässt. Er +# liegt AUSSERHALB der Datenbank; wer nur die Datenbank in die Hände bekommt, +# kann damit nichts fälschen, ohne dass es auffliegt. +# +# Generieren: openssl rand -hex 32 (pro Umgebung ein eigener Wert) +# +# Ohne Wert läuft alles normal weiter, nur eben ungesiegelt – nichts fällt aus. +# Nachträglich setzen ist jederzeit möglich: bestehende Einträge bleiben gültig, +# ab dem Neustart werden neue gesiegelt (keine Fehlalarme dadurch). +# +# ACHTUNG – einmal gesetzt, nicht wieder entfernen: Einträge, die ohne Schlüssel +# entstehen, werden beanstandet, sobald er zurück ist (ein ungesiegelter Eintrag +# inmitten gesiegelter ist von einer Fälschung nicht zu unterscheiden). +# Schlüssel sichern wie ein Passwort – geht er verloren, sind die damit +# gesiegelten Einträge dauerhaft nicht mehr prüfbar. +# Ausführlich erklärt in der README, Abschnitt "Audit-Siegel". +AUDIT_HMAC_KEY= + +# Nur beim Schlüsselwechsel füllen: die FRÜHEREN Schlüssel, kommagetrennt und +# jüngster zuerst. Damit bleiben die bisherigen Einträge prüfbar, während neue +# schon mit dem neuen Schlüssel gesiegelt werden. Nicht voreilig leeren – sonst +# werden die alten Einträge als "manipuliert" gemeldet. +# Beispiel: AUDIT_HMAC_KEY_OLD=, +AUDIT_HMAC_KEY_OLD= + # Server NODE_ENV=development PORT=3001 # Backend-internal Port (Dev: localhost:3001) diff --git a/README.md b/README.md index 9eaaba2a..236f6c4f 100644 --- a/README.md +++ b/README.md @@ -337,9 +337,20 @@ Hände bekommt, kann damit nichts fälschen, ohne dass es auffliegt. openssl rand -hex 32 ``` -Den Wert in die `.env` der jeweiligen Umgebung eintragen. Wichtig: **pro -Umgebung ein eigener Schlüssel** (Entwicklung, Test, Produktion) – und -niemals ins Git-Repository. +**In welche Datei?** Das hängt davon ab, wie du OpenCRM betreibst: + +| Betrieb | Datei | +|---|---| +| **Docker** (Standard, `docker-compose.yml` im Projektstamm) | **`.env` im Projektstamm** | +| Backend direkt, ohne Container (Entwicklung) | `backend/.env` | +| Alternativer Caddy-Stack unter `docker/` | `docker/.env` | + +Beim Docker-Betrieb reicht der Eintrag in der Stamm-`.env` – `docker-compose.yml` +reicht die Variable an den Container weiter. Ein Eintrag in `backend/.env` wirkt +dort **nicht**, weil der Container diese Datei nicht liest. + +Wichtig: **pro Umgebung ein eigener Schlüssel** (Entwicklung, Test, Produktion) +– und niemals ins Git-Repository. **Bestehende Installation: bisher kein Schlüssel gesetzt?** diff --git a/docker-compose.yml b/docker-compose.yml index f5ff0b75..6f3ce67e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -62,6 +62,12 @@ services: JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-15m} JWT_REFRESH_EXPIRES_IN: ${JWT_REFRESH_EXPIRES_IN:-7d} ENCRYPTION_KEY: ${ENCRYPTION_KEY} + # Siegel für das Audit-Log: signiert jeden Eintrag mit einem Schlüssel, + # der außerhalb der Datenbank liegt. Ohne Wert läuft alles normal weiter, + # nur ungesiegelt (fail-safe). AUDIT_HMAC_KEY_OLD nur beim Wechsel füllen + # (kommagetrennte Liste früherer Schlüssel). + AUDIT_HMAC_KEY: ${AUDIT_HMAC_KEY:-} + AUDIT_HMAC_KEY_OLD: ${AUDIT_HMAC_KEY_OLD:-} NODE_ENV: production PORT: 3001 LISTEN_ADDR: 0.0.0.0 diff --git a/docker/.env.example b/docker/.env.example index 4fe6d131..87ea08ca 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -27,3 +27,14 @@ ENCRYPTION_KEY=change-this-to-a-32-byte-hex-key # First Install: Set to "true" to seed database on first startup # After first successful start, set back to "false" RUN_SEED=true + +# ---------- Siegel für das Audit-Log ---------- +# Signiert jeden neuen Audit-Eintrag mit einem Schlüssel ausserhalb der +# Datenbank, damit sich die Beweisspur nicht nachtraeglich faelschen laesst. +# Generieren: openssl rand -hex 32 (pro Umgebung ein eigener Wert). +# Ohne Wert laeuft alles normal weiter, nur ungesiegelt. +# Einmal gesetzt nicht wieder entfernen - Details in der README. +AUDIT_HMAC_KEY= + +# Nur beim Schluesselwechsel: frueherer Schluessel, mehrere kommagetrennt. +AUDIT_HMAC_KEY_OLD= diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 7206d00d..24bc6f34 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -40,6 +40,9 @@ services: JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required} JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d} ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY is required} + # Siegel für das Audit-Log (optional, fail-safe ohne Wert) + AUDIT_HMAC_KEY: ${AUDIT_HMAC_KEY:-} + AUDIT_HMAC_KEY_OLD: ${AUDIT_HMAC_KEY_OLD:-} RUN_SEED: ${RUN_SEED:-false} volumes: - uploads_data:/app/uploads