feat: add OIDC browser sessions with live access enforcement
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
This commit is contained in:
parent
fdea2f5192
commit
a15fe032b0
14 changed files with 807 additions and 31 deletions
|
|
@ -99,3 +99,56 @@ A composed fixture journey verifies a real RSA JWT, fresh facts, an Ed25519
|
|||
policy decision, receiver custody and native Hub write, followed by entitlement
|
||||
withdrawal denial. Real root enrollment/login, service deployment, live key and
|
||||
sender custody, and operational acceptance remain open.
|
||||
|
||||
## Browser composition (source candidate)
|
||||
|
||||
Pass `browser_settings=BrowserSettings(origin="https://hub.example",
|
||||
client_id="hub-browser", client_secret_file=Path("/run/secrets/hub-oidc-client"))`
|
||||
to `create_app`, alongside the enforced controller or authoritative-facts security
|
||||
composition described above. Import `BrowserSettings` from
|
||||
`hub_core.security.browser`. Browser configuration cannot activate a development
|
||||
runtime or a missing controller. Its confidential-client credential is separate
|
||||
from the policy/audit workload credentials and is reread at each code exchange.
|
||||
|
||||
Register the exact HTTPS origin plus `/auth/callback` with the admitted issuer.
|
||||
The source candidate requires authorization code, S256 PKCE, RS256 ID tokens and
|
||||
`client_secret_basic` discovery support. It requests fresh authentication and
|
||||
AAL2; validated access-token assurance and current owner facts decide access.
|
||||
Issuer registration, actual MFA behavior, audience mapping and live owner
|
||||
acceptance remain deployment gates. The implementation follows the
|
||||
[OIDC ID token validation contract](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation)
|
||||
and [OAuth security best practices](https://www.rfc-editor.org/rfc/rfc9700.html).
|
||||
|
||||
- `GET /auth/login` initiates login; arbitrary query parameters are refused.
|
||||
- `GET /auth/callback` consumes browser-bound state once, exchanges the code with
|
||||
PKCE, checks signature/issuer/audience/nonce/authentication time/access binding,
|
||||
and requires root authorization and audit custody before issuing a session.
|
||||
- `GET /auth/session` rechecks authority and returns expiry and a CSRF token.
|
||||
- `POST /auth/logout` requires the session, exact `Origin` and `X-Hub-CSRF`, then
|
||||
destroys the local session even during identity/policy/audit outages.
|
||||
|
||||
Sessions contain access tokens only in server memory. Cookies carry random opaque
|
||||
IDs with `Secure`, `HttpOnly`, `SameSite=Lax`, host-only scope and `/` path. Sessions
|
||||
expire within five minutes or either token's expiry, whichever comes first;
|
||||
there is no refresh-token renewal. Process restart/shutdown invalidates sessions.
|
||||
Multiple workers need sticky routing or a separately reviewed shared session
|
||||
store; this candidate does not provide distributed sessions. Pending logins and
|
||||
sessions have bounded capacity. Production ingress must also rate-limit login.
|
||||
|
||||
All protected API requests recheck identity, current facts, signed policy and
|
||||
durable audit. Cookie-authenticated writes additionally require exact `Origin`
|
||||
and `X-Hub-CSRF`; browser clients obtain the latter from `/auth/session`. The
|
||||
bundled Swagger UI does not automatically inject that header. Mixed cookies and
|
||||
bearer credentials are rejected. Session expiry/logout is checked again after
|
||||
authority awaits and before dispatch. Logout cannot cancel already executing
|
||||
requests or log out the upstream identity provider; subsequent login requests
|
||||
fresh authentication. Logout is local invalidation, not a durable audited
|
||||
business mutation. Refused browser flows are recorded without codes/tokens/query
|
||||
parameters; audit failure returns 503. Login initiation does not require authority.
|
||||
|
||||
The app must observe the configured HTTPS origin. Do not trust arbitrary
|
||||
forwarded headers; configure an authenticated trusted proxy separately. Callback
|
||||
query strings are cleared before response-time application access logging, but
|
||||
reverse proxies and tracing collectors must independently suppress callback
|
||||
queries, cookies and authorization headers. No public listener is enabled by
|
||||
these source changes.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue