Files
govoplan-access/docs/AUTHENTICATION_CACHE_SECURITY.md
2026-09-08 01:32:20 +02:00

4.4 KiB

Authentication cache boundary hardening

The authentication cache is an optimization, never an additional authentication method or permission source. The September 2026 review found and reproduced three violations of that boundary in isolated SQLite tests.

Finding Consequence Resolution
Service-account credentials passed through ordinary principal-summary refresh A narrowed service-account ceiling could be replaced by backing membership roles; the service-account identifier and authentication method were lost. Dedicated service-account resolution retains its provenance and checks the current ceiling/lifecycle on every request. It does not enter the interactive principal-summary cache.
A warmed API-key summary accepted the same secret through a session cookie The warm path accepted a cookie-authenticated mutation without the CSRF rule applied to real browser sessions; the cold path rejected the credential. API keys require an explicit Bearer or X-API-Key header on both paths. Session cookies still require matching CSRF cookie/header/hash for mutations.
Tenant-key intersection excluded only the historical system: spelling Module-native system permissions and retained module wildcards could survive the tenant-only intersection. Resolve wildcard grants to concrete registered tenant permissions and exclude system permissions by catalogue and compatibility aliases.

No existing secrets, sessions, assignments, or database schema are changed. Normal header-authenticated API keys and concrete tenant aliases remain compatible. Clients relying on API keys in browser cookies, implicit unknown wildcards, or accidental instance-level rights must correct their authentication method or permission configuration; these are not preserved as compatibility exceptions. Stored grants are not rewritten. Service-account access continues to narrow immediately when its ceiling is reduced or its lifecycle blocks use.

Regression coverage is in tests/test_auth_cache_security.py and tests/test_permission_catalog_contract.py; the tests exercise the full credential resolver with principal caching enabled, not only the lower-level API-key lookup. They also verify that valid session CSRF and concrete legacy tenant aliases still work.

Remaining coordinated password-change workflow

Account.password_reset_required is currently advisory metadata, not an enforced sign-in restriction. The administrator UI states this limitation, but the authentication-fields documentation previously claimed mandatory replacement; its English and German text now reflects the implementation. A generated password is disclosed once but is not a single-use login secret.

A follow-up must deliver the password-change endpoint, current-password verification and replacement policy, CSRF and attempt limits, session revocation/rotation and cache invalidation, a restricted reset-required principal, and the corresponding accessible UI/recovery path together. Enabling only a rejection gate would lock affected accounts out without any supported way to finish the change. This review does not enable such a gate or change existing passwords.

Betriebshinweise

API-Schlüssel werden ausschließlich über Authorization: Bearer oder X-API-Key gesendet, nicht über das Sitzungscookie. Ändernde Cookie-Anfragen benötigen weiterhin einen passenden CSRF-Header samt Cookie und serverseitigem Prüfwert. Dienstkonten behalten ihre eigene Herkunft und werden bei jeder Anfrage gegen den aktuellen Berechtigungsrahmen und Lebenszyklus geprüft. Mitgliedschaftsrollen oder zwischengespeicherte interaktive Rechte dürfen diesen Rahmen nicht ersetzen.

Mandantenschlüssel erhalten keine instanzweiten Rechte, auch nicht unter modulbezogenen Berechtigungsnamen. Platzhalter werden in konkrete registrierte Mandantenrechte aufgelöst. Bestehende konkrete Mandantenrechte und ihre Kompatibilitätsnamen bleiben erhalten; gespeicherte Geheimnisse und Rollenzuweisungen werden nicht geändert.

Das Kennzeichen password_reset_required erzwingt derzeit keinen Passwortwechsel. Ein einmal angezeigtes Anfangspasswort bleibt zur Anmeldung verwendbar. Die Nachfolgeumsetzung muss Passwortänderung, eng begrenzten Zwischenzugriff, Sitzungswechsel beziehungsweise Widerruf und eine bedienbare Wiederherstellung gemeinsam liefern; eine alleinige Zugriffssperre würde betroffene Konten ohne durchführbaren Passwortwechsel aussperren.