From 6151cbe2ed4700a15d6142c3307d22199f1ebdee Mon Sep 17 00:00:00 2001 From: patrick Date: Sun, 20 Sep 2026 23:28:24 +0200 Subject: [PATCH] INT-01: qa02-gate prueft api-auth, betriebsdoku fuer identitaets-variablen --- dms/docs/BETRIEB-UMGEBUNGSVARIABLEN.md | 12 +++++++++++- scripts/qa02-rebuild-from-scratch.sh | 9 +++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/dms/docs/BETRIEB-UMGEBUNGSVARIABLEN.md b/dms/docs/BETRIEB-UMGEBUNGSVARIABLEN.md index 9415a898..4139c42e 100644 --- a/dms/docs/BETRIEB-UMGEBUNGSVARIABLEN.md +++ b/dms/docs/BETRIEB-UMGEBUNGSVARIABLEN.md @@ -10,9 +10,19 @@ Aus dem Code abgeleitet (`cmd/app`, `cmd/worker`, `cmd/migrate`, `internal/route |---|---|---| | `NEXARCH_DMS_APP_LISTEN_ADDR` | `:8600` | Lauschadresse | | `NEXARCH_DMS_APP_ROUTE_PREFIX` | `/api/dms/v1` | Präfix aller fachlichen Routen (FDN-14); `/healthz` und `/metrics` bleiben außerhalb | -| `NEXARCH_DMS_APP_TENANT_DSN` | Pflicht für Fachfunktionen | Tenant-Datenbank; ohne sie: kein Guard, keine Retention-Anbindung, keine Suche | +| `NEXARCH_DMS_APP_TENANT_DSN` | Pflicht für Fachfunktionen | Tenant-Datenbank; ohne sie: keine API-Routen, kein Guard, keine Retention-Anbindung, keine Suche | | `NEXARCH_DMS_APP_TENANT_SLUG` | Pflicht | Mandantenkennung | | `NEXARCH_DMS_APP_ADMIN_USER_IDS` | leer | Kommagetrennte Nutzer-IDs mit Admin-Rechten im Guard | +| `NEXARCH_DMS_APP_CORE_JWKS_URL` | Pflicht (oder Übergangsschalter) | JWKS-Endpunkt von Core; Bearer-Token werden lokal gegen diesen Schlüsselsatz geprüft (INT-01, `docs/API.md`). Ohne sie und ohne Übergangsschalter startet dms-app mit DSN nicht | +| `NEXARCH_DMS_APP_JWKS_TTL_SECONDS` | 300 | Cache-Dauer des Schlüsselsatzes; bei Core-Ausfall gilt der letzte bekannte Satz weiter | +| `NEXARCH_DMS_APP_ALLOW_CALLER_IDENTITY` | `false` | Übergang: `true` lässt Anfragen ohne Token mit `caller`-Parameter als Identität zu (nicht authentifiziert, nur Entwicklung) | +| `NEXARCH_DMS_APP_POLICY_URL` / `_POLICY_SERVICE_TOKEN` | Aus | Core-Policy-Endpunkt (RBAC-06, `POST /authorize`); aktiviert die Rechteprüfung je Route (`x-permission` der OpenAPI-Beschreibung). Token ist Secret; Ausfall lehnt ab | +| `NEXARCH_DMS_APP_POLICY_DEFAULT_ROLE` / `_POLICY_TTL_SECONDS` | `user` / 30 | Rolle ohne `role`-Claim im Token; Cache-Dauer der Entscheidungen | +| `NEXARCH_DMS_APP_STAGING_DIR` | Pflicht bei DSN (Rückfall: `NEXARCH_DMS_APP_WATCHFOLDER_STAGING_DIR`) | Staging der Upload-Blöcke | +| `NEXARCH_DMS_APP_DOWNLOAD_SIGNING_SECRET` | Pflicht bei DSN | Schlüssel für Download-URLs (Secret) | +| `NEXARCH_DMS_APP_DOWNLOAD_URL_TTL_SECONDS` | 300 | Gültigkeit signierter Download-URLs | +| `NEXARCH_DMS_APP_TRASH_RETENTION_SECONDS` | 2592000 (30 Tage) | Papierkorb-Frist | +| `NEXARCH_DMS_APP_AUDITOR_USER_IDS` | leer | Nutzer-IDs mit Zugriff auf `/audit-log` | | `NEXARCH_DMS_APP_STORAGE_DIR` | Pflicht | Lokales Storage-Verzeichnis | | `NEXARCH_DMS_APP_STORAGE_SIGNING_SECRET` | Pflicht | Schlüssel für signierte URLs (Secret) | | `NEXARCH_DMS_APP_STORAGE_PUBLIC_BASE_URL` | Pflicht | Basis-URL signierter Links | diff --git a/scripts/qa02-rebuild-from-scratch.sh b/scripts/qa02-rebuild-from-scratch.sh index cbbb8ed2..d74bfbb8 100755 --- a/scripts/qa02-rebuild-from-scratch.sh +++ b/scripts/qa02-rebuild-from-scratch.sh @@ -47,6 +47,8 @@ step "dms-app startet auf 127.0.0.1:$port" NEXARCH_DMS_APP_LISTEN_ADDR="127.0.0.1:$port" NEXARCH_DMS_APP_TENANT_DSN="$dsn" NEXARCH_DMS_APP_TENANT_SLUG=qa02 \ NEXARCH_DMS_APP_STORAGE_DIR="$tmp/storage" NEXARCH_DMS_APP_STORAGE_SIGNING_SECRET="$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')" \ NEXARCH_DMS_APP_STORAGE_PUBLIC_BASE_URL="http://127.0.0.1:$port" \ + NEXARCH_DMS_APP_STAGING_DIR="$tmp/staging" NEXARCH_DMS_APP_CORE_JWKS_URL="http://127.0.0.1:1/jwks" \ + NEXARCH_DMS_APP_DOWNLOAD_SIGNING_SECRET="$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')" \ "$tmp/bin/app" >"$tmp/app.log" 2>&1 & app_pid=$! up=0 @@ -57,6 +59,13 @@ for _ in $(seq 1 30); do done if [ "$up" = 1 ] && grep -q '"status":"ok"' "$tmp/health.json"; then ok; else bad "kein /healthz: $(tail -3 "$tmp/app.log")"; fi +step "API: Beschreibung offen, alles andere ohne gueltiges Token 401 im Core-Fehlerformat" +api="http://127.0.0.1:$port/api/dms/v1" +code_spec=$(curl -s -o /dev/null -w '%{http_code}' "$api/openapi.json") +code_anon=$(curl -s -o "$tmp/anon.json" -w '%{http_code}' "$api/tags") +code_bad=$(curl -s -o /dev/null -w '%{http_code}' -H 'Authorization: Bearer ungueltig' "$api/tags") +if [ "$code_spec" = 200 ] && [ "$code_anon" = 401 ] && [ "$code_bad" = 401 ] && grep -q '"code":"unauthenticated"' "$tmp/anon.json"; then ok; else bad "spec=$code_spec anon=$code_anon bad=$code_bad $(cat "$tmp/anon.json")"; fi + step "/metrics erreichbar" if curl -fsS "http://127.0.0.1:$port/metrics" | grep -q dms_http_requests_total; then ok; else bad "keine metrics"; fi