From b89289989a39ab358dc569c1d206c235c1efa6de Mon Sep 17 00:00:00 2001 From: DevOps Date: Sun, 21 Jun 2026 10:28:53 +0200 Subject: [PATCH] docs: document owner password persistence fix in deployment.md and changelog --- phases/changelog.md | 11 ++++++++++- phases/deployment.md | 25 ++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/phases/changelog.md b/phases/changelog.md index 8cfd97e..c4dca20 100644 --- a/phases/changelog.md +++ b/phases/changelog.md @@ -1,6 +1,15 @@ # Changelog -> Letzte Aktualisierung: 2026-06-20 +> Letzte Aktualisierung: 2026-06-21 + +- 2026-06-21: **Permanenter Owner-Passwort-Persistenz-Fix (SeedAudit + Single Source of Truth).** + - Root Cause: Dual-Source-Architektur (Gitea-Secret vs Host-.env) verursachte Passwort-Drift nach DB-Reseed. + - Code-Fix: `SeedAudit`-Entity + Migration (`20260621081500_AddSeedAudit`) eingebaut. `EnsureDatabaseAsync` prueft jetzt `SeedAudit` VOR dem Seeden. Key `owner_created` blockiert erneutes Seeden permanent. + - Workflow-Fix: Deploy- und Rollback-Workflows lesen `OWNER_PASSWORD` aus dem Host-`.env` (Single Source of Truth), nicht mehr aus Gitea-Secret. + - `compose.yaml`: Kommentar hinzugefuegt dass OWNER_PASSWORD nur beim initialen Seed verwendet wird. + - Verifikation: Login funktioniert nach `docker compose down && up`, `--force-recreate`, und `restart`. + - Git: Commit `f95463e`, manuell ausgerollt. + - Betroffene Dateien: `ApplicationBuilderExtensions.cs`, `Identity.cs`, `NexusDbContext.cs`, `20260621081500_AddSeedAudit.cs`, `NexusDbContextModelSnapshot.cs`, `deploy.yaml`, `rollback.yaml`, `compose.yaml`, `nexus.md`, `phases/deployment.md`. - 2026-06-20: **Agent-Progress-Visibility live ausgerollt; normaler Gitea-Deploy-Trigger weiter defekt.** - Feature-Stand auf `main`: `adae7ba` (`feat: ship agent progress visibility`); nach CI-Blocker-Fix `2d21885` (`Fix activity repository test double`) war CI fuer Backend, Frontend und Security gruen. diff --git a/phases/deployment.md b/phases/deployment.md index 57c4346..b04810b 100644 --- a/phases/deployment.md +++ b/phases/deployment.md @@ -1,7 +1,7 @@ # Deployment -> Letzte Aktualisierung: 2026-06-20 -> Status: ✅ CD v3 (Auto + Manual) +> Letzte Aktualisierung: 2026-06-21 +> Status: ✅ CD v3 (Auto + Manual) + Owner-Passwort-Persistenz (SeedAudit) > Live-URL: https://nexus.noveria.net ## CD-Philosophie (v3) @@ -107,6 +107,23 @@ schedule: ## Secrets und Konfiguration +### Owner Password Persistence (2026-06-21, permanent fix) + +**Root Cause**: Dual-Source-Architektur fuer das Owner-Passwort (Gitea-Secret `ENV_OWNER_PASSWORD` vs Host `.env` `OWNER_PASSWORD`) verursachte Drift wenn die DB jemals neu geseedet wurde. + +**Fix (3 Schichten)**: +1. **SeedAudit-Entity** (DB-Migration `20260621081500_AddSeedAudit`): `EnsureDatabaseAsync` prueft die `SeedAudit`-Tabelle auf Key `owner_created` VOR dem Seeden. Ist dieser Key vorhanden, wird der Owner NIE neu erstellt — selbst wenn die Users-Tabelle komplett geloescht wird. +2. **Single Source of Truth**: Deploy- und Rollback-Workflows lesen `OWNER_PASSWORD` jetzt aus dem persistenten Host-`.env` (via `grep` auf dem Deploy-Pfad), NICHT mehr aus separatem Gitea-Secret. Das Host-`.env` ist die kanonische Quelle. +3. **admin-reset-password** Endpoint existiert als Recovery-Pfad (braucht `Admin__ResetToken` aus dem `.env`). + +**Verifikation (2026-06-21)**: +- Login funktioniert nach `docker compose down && up` (kompletter Stack-Neustart) +- Login funktioniert nach `docker compose up -d --force-recreate --wait` +- Login funktioniert nach `docker compose restart` +- SeedAudit-Eintrag `owner_created` blockiert erneutes Seeden bei jedem Startup + +**Regel gegen Wiederholung**: `OWNER_PASSWORD` nur im Host-`.env` aendern. Das Host-`.env` wird von CI-Deploys gelesen. Niemals ein separates Gitea-Secret fuer OWNER_PASSWORD anlegen. + ### Secrets in Gitea Folgende Secrets sind in Gitea (Repo → Settings → Actions → Secrets) konfiguriert: @@ -115,9 +132,11 @@ Folgende Secrets sind in Gitea (Repo → Settings → Actions → Secrets) konfi |---|---| | `ENV_POSTGRES_PASSWORD` | PostgreSQL-Passwort | | `ENV_JWT_KEY` | JWT-Signing-Key (min. 32 Bytes) | -| `ENV_OWNER_PASSWORD` | Owner-Account-Passwort | | `ENV_OPENCLAW_TOKEN` | OpenClaw Gateway Token | +> **Hinweis**: `ENV_OWNER_PASSWORD` wurde aus den Gitea-Secrets ENTFERNT (2026-06-21). +> OWNER_PASSWORD kommt ausschliesslich aus dem Host-`.env` auf dem Deploy-Pfad. + ### Safe Secret Handling (v3) **Vorher (unsicher)**: Secrets wurden via `${{ secrets.X }}` direkt in eine Datei im Workspace interpoliert, die dann zum Host synct wurde. Das `.env` lag potenziell lesbar im Workspace und auf dem Host-Dateisystem.