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.
5.0 KiB
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/authorizeHandler—POST /authorize, reiner Wrapper umenforcer.Authorize.cmd/policy-api— eigenständiger HTTP-Dienst (analog zu den bestehenden*-devservern, getrennt voncmd/core).
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Endpunkt-Antwort stimmt in 100 Stichproben exakt mit dem direkten Enforcer.Authorize-Ergebnis überein | bestanden — TestAuthorizeHandler_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 | bestanden — TestRequireServiceToken_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-apigebaut nach/opt/nexarch-core/bin//etc/nexarch/policy-api.env(0600)nexarch-policy-api.serviceinstalliert/aktiviert (dauerhaft,Restart=on-failure)- Reale Rechtevergabe-Lücke gefunden und behoben:
policy_rules/policy_rule_changeswaren aufnexarch_registrybereits von einem früheren Testlauf unter der Rollepostgresangelegt worden,nexarch_corehatte keine Rechte darauf —GRANTnachgezogen - Realer End-zu-Ende-Test via
curl: 401 ohne Token,{"allowed":false}für unbekannte Kombination,{"allowed":true}nach echtemGrant, 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.