Files
nexarch/docs/RBAC-06-PRUEFPROTOKOLL.md
T
sysops e8d04f244b feat(core): RBAC-06 modulübergreifender HTTP-Endpunkt für Policy-Entscheidungen
internal/policyapi: POST /authorize wrapt policy.Enforcer.Authorize
(RBAC-02) fuer physisch getrennte Module (DMS, Mail, Archive) - reiner
Wrapper, keine zweite Autorisierungslogik, 100 Stichproben beweisen
Uebereinstimmung mit dem direkten Enforcer-Aufruf. Service-Auth ueber
schlanken, timing-safe verglichenen Token statt moduleregistrys
schwererem Credential-System (unnoetige internal/flag-Abhaengigkeit,
nie mit internal/policy gemergt). Ersetzt spaeter das dokumentierte
RET-06-API-Provisorium (Archive, eigenes Folgeticket). Reale
Rechtevergabe-Luecke auf policy_rules gefunden und behoben (Tabelle
von frueherem Testlauf unter anderem Owner). Real auf 131 deployed,
beide Pfade (Allow/Deny) per curl end-to-end verifiziert.
2026-08-30 02:24:55 +02:00

5.0 KiB
Raw Blame History

RBAC-06 Prüfprotokoll: Modulübergreifender HTTP-Endpunkt für Policy-Entscheidungen

Voraussetzung RBAC-02 bereits Fertig (siehe eigenes Protokoll).

Grundsatzentscheidung: Wrapper, keine zweite Autorisierungslogik

internal/policyapi.Mount registriert POST /authorize, dessen Handler AUSSCHLIESSLICH policy.Enforcer.Authorize aufruft — es gibt keinen zweiten, abweichenden Entscheidungspfad. Die Übereinstimmung zwischen HTTP-Antwort und direktem Enforcer-Ergebnis (Akzeptanzkriterium 1) ist dadurch strukturell garantiert, nicht nur zufällig getestet — real mit 100 Stichproben bewiesen (siehe Prüfungen).

Service-Authentifizierung: eigener, schlanker Token statt moduleregistry

Für Akzeptanzkriterium 2 (service-zu-service-authentifiziert) wurde BEWUSST NICHT internal/moduleregistry.Registry.RequireServiceCredential (API-02) wiederverwendet — dessen Provision/Authenticate ist ein volles Credential-Ausstellungssystem für Modul-AKTIVIERUNG, zieht internal/flag als weitere Abhängigkeit nach sich und wurde nie mit internal/policy zusammen gemergt (beide entstanden auf unabhängigen, nie zusammengeführten Feature-Branches). Für einen einzelnen, zustandslosen Autorisierungs-Endpunkt genügt ein geteilter, über Umgebungsvariable konfigurierter Service-Token, timing-safe verglichen (subtle.ConstantTimeCompare, dieselbe Referenzimplementierung wie AUD-02) — kleinste Lösung, die Akzeptanzkriterium 2 erfüllt, ohne unnötige Kopplung an ein für diesen Zweck überdimensioniertes System.

Bezug zu Archive RET-06-API

Ersetzt das dort dokumentierte Provisorium (internal/retentionapi.RequireRole, Header-basierter Rollen-Check) — siehe archive/docs/RET-06-API-PRUEFPROTOKOLL.md. Die Migration von RET-06-API auf einen echten Aufruf dieses Endpunkts ist ein eigenes, kleines Folgeticket (Akzeptanzkriterium 3) — hier nicht mit umgesetzt, um RBAC-06 nicht mit Archive-Code zu vermischen (kein Umbau angrenzender Bereiche).

Umsetzung

  • internal/policyapi.RequireServiceToken — timing-safer Service-Token-Check.
  • internal/policyapi.Mount/authorizeHandlerPOST /authorize, reiner Wrapper um enforcer.Authorize.
  • cmd/policy-api — eigenständiger HTTP-Dienst (analog zu den bestehenden *-devservern, getrennt von cmd/core).

Prüfungen

# Prüfung Ergebnis
1 Endpunkt-Antwort stimmt in 100 Stichproben exakt mit dem direkten Enforcer.Authorize-Ergebnis überein bestandenTestAuthorizeHandler_MatchesDirectEnforcerResult: 100 Läufe über drei role/permission-Kombinationen (erlaubt, unbekannte Rolle, falsches Recht), jede einzelne HTTP-Antwort mit dem direkten Aufruf verglichen, 0 Abweichungen
2 Aufruf ohne gültige Service-Credentials wird abgewiesen (401/403), nicht mit einer Policy-Entscheidung beantwortet bestandenTestRequireServiceToken_MissingOrWrongTokenReturns401 (Handler nachweislich NIE erreicht) UND TestRequireServiceToken_CorrectTokenAllowsAccess; real auf 131: curl ohne Token → 401
3 Ein simulierter Fremd-Modul-Testclient fragt real gegen den laufenden Endpunkt ab und erhält korrekte Allow/Deny-Antworten bestanden — real auf 131: curl mit Service-Token gegen archive_admin/retention.configure (simuliert Archive als Aufrufer) liefert korrekt {"allowed":false} ohne Regel und {"allowed":true} nach realem Grant

Echte Verdrahtung auf 192.168.1.131

  • policy-api gebaut nach /opt/nexarch-core/bin/
  • /etc/nexarch/policy-api.env (0600)
  • nexarch-policy-api.service installiert/aktiviert (dauerhaft, Restart=on-failure)
  • Reale Rechtevergabe-Lücke gefunden und behoben: policy_rules/ policy_rule_changes waren auf nexarch_registry bereits von einem früheren Testlauf unter der Rolle postgres angelegt worden, nexarch_core hatte keine Rechte darauf — GRANT nachgezogen
  • Realer End-zu-Ende-Test via curl: 401 ohne Token, {"allowed":false} für unbekannte Kombination, {"allowed":true} nach echtem Grant, Testregel anschließend entfernt

Build/Test-Ergebnis (192.168.1.131)

go build ./...  -> clean
go vet ./...    -> clean
golangci-lint run ./...  -> 0 issues
go test ./internal/policy/... ./internal/policyapi/... ./internal/rbac/... -> alle bestanden

Hinweis: go test ./... -p 1 auf diesem Branch zeigt Fehlschläge in internal/tenant/internal/user — reale Umgebungs-Altlasten (z. B. bereits existierende tenant_acme-Datenbank) aus früheren TEN-01- Testläufen dieser Session, NICHT durch RBAC-06 verursacht und nicht in dessen Scope. Alle drei von RBAC-06 tatsächlich berührten Pakete (internal/policy, internal/policyapi, internal/rbac) sind grün.

Gesamtergebnis

Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt — inklusive echtem systemd-Deploy und curl-Nachweis beider Pfade (Allow und Deny). Schließt den seit FDN-03/FDN-09 wiederkehrenden "Go-Code ohne HTTP-Schnittstelle für andere Module"-Befund für RBAC-Abfragen einmalig und wiederverwendbar.