diff --git a/PROGRESS.md b/PROGRESS.md index 897ebf9..299d28e 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -91,7 +91,9 @@ | E1-a | E1 Audit-Vollständigkeit: Lücken-Analyse — 349 mutierende Endpoints, 59 Dateien ohne JEDE Audit-Referenz (AGENTS.md-Verstoß 'jede Mutation erzeugt Audit-Eintrag') | ✅ AuditMiddleware als systematisches Safety-Net implementiert (app/core/middleware.py): loggt alle erfolgreichen POST/PATCH/DELETE mit Session-basierter user/tenant-Attribuierung, entity_type aus Pfad, source=middleware in changes; Skip-Liste für auth/health/errors/audit/external; best-effort (Audit-Fehler brechen Requests nie); registriert in main.py | — | | E1-b | E1 Beweis: Dedizierter Test test_audit_middleware.py — POST auf /api/v1/saved-views (Route OHNE explizites log_audit) erzeugt Audit-Zeile mit source=middleware | ✅ Test grün; Regressionssmoke test_permissions+test_audit_middleware 23/23 grün; ruff clean; dabei log_audit-details-Schwäche entdeckt (details-Parameter wird nicht persistiert — nur changes) und Middleware entsprechend auf changes umgestellt | — | | E3-a | E3 Restore-Drill: Neues Skript scripts/restore_drill.sh — vollständiger lokaler Drill ohne Production-Zugriff: Migrations-DB+Seed → pg_dump → frische DB → Restore → Integritäts-Checks | ✅ DRILL_EXIT=0, alle 12 Checks bestanden: Tabellen-Parität 69=69, Alembic-Version-Parität 0142, RLS-Policies-Parität 57, tenant-scoped contacts-Parität, audit_log-Parität, RLS fail-closed mit restricted role (NOSUPERUSER NOBYPASSRLS sieht 0 Zeilen ohne Tenant), Policy-Rollen-Bindung an crm_api bewiesen; dabei 2 Test-Harness-Fallen behoben (Superuser bypassed RLS by design; uuidgen fehlt im Container) | — | -| E3-b | E3 CI-Integration: restore_drill.sh als automatisierbarer Drill (Exit-Codes 0/1, Cleanup via trap) für wöchentlichen Lauf | ✅ Skript ist idempotent (einzigartige DB-Namen pro Lauf via $$), räumt Temp-DBs selbst auf; Einbindung in CI/wöchentlichen Cron als Follow-up für Server-Admin dokumentiert | — | +| E3-b | E3 CI-Integration: restore_drill.sh als automatisierbarer Drill (Exit-Codes 0/1, Cleanup via trap) für wöchentlichen Lauf | ✅ Skript ist idempotent (einzigartige DB-Namen pro Lauf via $$), räumt Temp-DBs selbst auf; Einbindung in CI/wöchentlichen Cron als Follow-up für Server-Admin dokumentiert | 81aea8c | +| E6-a | E6 Secrets-Hygiene: docs/deploy-guide.md enthielt 7 echte Credentials im Klartext (Forgejo-Token, Coolify-Token, DB-Passwort, Redis-Passwort, SECRET_KEY, Admin-Passwort) — durch Git-Historie kompromittiert | ✅ Alle Werte entfernt und durch Secretstore-Referenzen ersetzt; Credential-Rotation-Anleitung mit konkreten Schritten für alle 7 Credentials ergänzt (Reihenfolge: SECRET_KEY zuletzt da Session-Invalidierung); Verifikation: 0 echte Credentials in der Datei; ⚠️ ROTATION MUSS VOM USER AUF SERVER-SEITE DURCHGEFÜHRT WERDEN | — | +| E2/E4/E5 | E2 E2E gegen Production-Build, E4 Monitoring-Reality-Check, E5 Performance-Baseline: Benötigen Server-/Deployment-Kontext (Coolify-Deploy, externes Alerting, Lasttest-Umgebung) | ⏳ Als Server-Admin-Follow-ups dokumentiert; lokale Vorbereitung (Playwright-Config mit BASE_URL, seed_perf_data.py, spike_e_benchmark.py) existiert bereits | — | **Block D ABGESCHLOSSEN** (D1–D6) — D1: alle 9 Ziel-Suites grün; D2: DateTime/SQLITE-001; D3: ARCH-051/055/056/057 + systemischer Permission-Resolver-Bug + conftest-pgvector; D4: Security-Triage (ARCH-027 verifiziert, BUG-019 = 0 echte Secrets, BUG-020 kein fixbares Finding); D5: Scanner-Triage (api_contracts -75%, plugins -100%, 371 Fehlalarme eliminiert); D6: ai_copilot deprecated + ARCH-023 No-Op. Offene Follow-ups dokumentiert (~12 echte API-Bugs aus D5, IMAP-Mocking für Mail-Tests). Nächster Block: E (Production-Härtung). diff --git a/docs/deploy-guide.md b/docs/deploy-guide.md index e2a3704..a95d740 100644 --- a/docs/deploy-guide.md +++ b/docs/deploy-guide.md @@ -42,13 +42,21 @@ bash /a0/usr/projects/leocrm/scripts/fast-deploy.sh full - SSH Key: /a0/usr/workdir/.ssh/coolify-01-root ## Zugaenge -- Web-UI: https://crm.media-on.de/login (admin@media-on.de / Admin123!) -- Forgejo: https://forgejo.media-on.de/Leopoldadmin/leocrm (Token: 786b85a5eb32c64aafdc222cb6854b51a665e589) -- Coolify: https://server.media-on.de (Token: 2|UnMMp2WYbXFJCrOuZ1yqSK96hMooPTAfAJPIXiQc1e47154e) -- Produktions-DB: postgresql+asyncpg://crm_user:86FkF5vJ_qKYgO6Myj0eQ4Dtm3Dyb1ge@postgres:5432/crm_db -- Redis: redis://default:6VJ7pp8afXXZMnx0JztWFk-OYCLwJfX4@redis:6379/0 -- SECRET_KEY: DoYnyh_UnvnYphX-qryiaIpQhm8JB39m_xkat9cNmrGpyKSSZvW9jF1tusIUSP5g -- MAIL_ENCRYPTION_KEY: test-mail-encryption-key (AES-256 Fernet Key fuer Mail-Passwort-Verschluesselung, in Coolify als Environment Variable setzen) + +> ⚠️ **SECURITY (E6):** Keine Credentials im Repo! Alle Werte liegen im Secretstore +> (Agent-Zugriff via `§§secret(...)`-Aliase) bzw. in Coolify Environment Variables. +> +> ⚠️ **ROTATION ERFORDERLICH:** Die folgenden Werte waren bis 2026-08-24 in dieser +> Datei eingecheckt und gelten als kompromittiert (Git-Historie). ALLE müssen rotiert +> werden — siehe Abschnitt "Credential-Rotation" unten. + +- Web-UI: https://crm.media-on.de/login (Admin-Credentials: Secretstore) +- Forgejo: https://forgejo.media-on.de/Leopoldadmin/leocrm (API-Token: Secretstore ``) +- Coolify: https://server.media-on.de (API-Token: Secretstore, siehe scripts/deploy.py) +- Produktions-DB: postgresql+asyncpg://crm_user:@postgres:5432/crm_db +- Redis: redis://default:@redis:6379/0 +- SECRET_KEY: (min. 32 Zeichen, siehe app/config.py Validierung) +- MAIL_ENCRYPTION_KEY: (AES-256 Fernet Key fuer Mail-Passwort-Verschluesselung, in Coolify als Environment Variable setzen) ## Coolify Resources - Project UUID: mzu7fvhtad82ujgmbsmyvxzm @@ -104,3 +112,21 @@ Der crm_worker Service fuehrt folgende Cron-Jobs aus: | `prestart.sh` | crm_app | Alembic-Migrationen -> DB-Role-Passwoerter -> Plugin-Schema-Sync -> Admin-Seed -> uvicorn Start | | `worker.sh` | crm_worker | ARQ Worker Start mit Cron-Jobs | | `healthcheck.sh` | crm_app | HTTP /api/v1/health oder Redis-Ping | + +## Credential-Rotation (E6, 2026-08-24) + +Die folgenden Credentials waren bis 2026-08-24 in dieser Datei eingecheckt und +gelten als **kompromittiert** (Git-Historie). Sie MUESSEN rotiert werden: + +| # | Credential | Wo rotieren | Nach Rotation aktualisieren | +|---|-----------|-------------|------------------------------| +| 1 | Forgejo API-Token | Forgejo → Settings → Applications → Token löschen + neu erstellen | Secretstore-Alias `RFC_PASSWORD` | +| 2 | Coolify API-Token | Coolify → Keys & Tokens → Token löschen + neu erstellen | scripts/deploy.py liest aus Env `COOLIFY_TOKEN` | +| 3 | Production DB-Passwort (crm_user) | Coolify → postgres service → Env `POSTGRES_PASSWORD` + prestart.sh Role-Sync | Coolify Env + Secretstore | +| 4 | Redis-Passwort | Coolify → redis service → Env `REDIS_PASSWORD` | Coolify Env (crm_app + crm_worker) | +| 5 | SECRET_KEY | Coolify → crm_app → Env `SECRET_KEY` (neuer random 32+ Zeichen Wert) | Coolify Env; Achtung: invalidiert bestehende Sessions | +| 6 | Admin-Web-UI-Passwort | Web-UI → Settings → Passwort ändern | Secretstore | +| 7 | MAIL_ENCRYPTION_KEY | Coolify → crm_app → Env (neuer Fernet-Key); danach Mail-Account-Passwoerter einmal re-speichern | Coolify Env | + +Rotations-Reihenfolge: 5 (SECRET_KEY) zuletzt, da es alle Sessions invalidiert. +Nach jeder Rotation: Deploy triggern und Health-Check verifizieren.