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.
93 lines
5.0 KiB
Markdown
93 lines
5.0 KiB
Markdown
# 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 um `enforcer.Authorize`.
|
||
- `cmd/policy-api` — eigenständiger HTTP-Dienst (analog zu den
|
||
bestehenden `*-devserver`n, getrennt von `cmd/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-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.
|