Web sign-in
A web product should complete OIDC authorization code with PKCE S256 in its backend and give the browser only a product session cookie. The repository’s Node.js and FastAPI examples demonstrate this pattern with injected tests. The owned issuer resolves multiple confidential registrations, and mounted HTTPS acceptance exercises two synthetic apps with separate sessions and verified audiences. Reviewed installation of real product clients remains gated on the registration writer and signed readback. The Node runtime also requires an approved lifecycle consumer; its tests use injected dependencies and run without a live issuer.
Configure the backend
Obtain a separately reviewed confidential client with an exact HTTPS callback and client secret. Configure the exact issuer, client ID, secret, application origin, and a server-side session store. Use a maintained OIDC library and discovery. Never construct authorization or token URLs by guessing paths from an earlier deployment.
cd examples/node
npm ci
npm test For a live run after multi-client registration, set these runtime variables from the approved registration and private deployment configuration:
| Variable | Value |
|---|---|
OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET | Exact HTTPS issuer and confidential client credentials. |
APP_ORIGIN, PORT | Trusted HTTPS origin and loopback server port, default 8002. Register APP_ORIGIN/callback and APP_ORIGIN/backchannel-logout. |
PROJECT_ID, LIFECYCLE_URL | Approved project ID and exact HTTPS /v1/lifecycle/{project_id} URL. |
LIFECYCLE_SERVICE_TOKEN, LIFECYCLE_PUBLIC_KEY_FILE | Short-lived project-scoped service token and dedicated lifecycle verification key file. |
cd examples/node
npm start Open APP_ORIGIN/login through trusted HTTPS ingress. The Node reference sends openid profile with state, nonce and PKCE S256 and verifies the returned ID token. After login, GET / returns a shape like this, using the actual issuer and subject rather than these illustrative values:
{"identity":{"issuer":"https://issuer.example.test","subject":"SUBJECT_FROM_ID_TOKEN"},"product_access":"not granted by OIDC"} The protected /workforce route checks lifecycle state, then returns 403 until a product-specific role adapter is supplied. Example sessions and lifecycle state are in memory, so they must be replaced before a real deployment.
Python backend alternative
examples/fastapi uses Authlib and a signed, Secure, HttpOnly session cookie. Set OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, APP_ORIGIN, and SESSION_SECRET (at least 32 random characters) in a private runtime environment. Register the exact APP_ORIGIN/callback URL, then run:
cd examples/fastapi
uv sync --locked
uv run pytest -q
uv run uvicorn app:build_app --factory --host 127.0.0.1 --port 8001 Serve the loopback process through trusted HTTPS at APP_ORIGIN. Open APP_ORIGIN/login. Its / response contains identity.issuer, identity.subject, and product_access: not granted by this example; it does not implement lifecycle or product roles.
Complete the callback
Bind each authorization attempt to a server-side transaction. Compare the returned state, redeem the code once using the original verifier, validate nonce and the signed ID token’s issuer, audience, expiry, and subject. Create a local product session keyed to (iss, sub) only after mapping it to an existing authorized local account. Store the browser session in a Secure, HttpOnly, SameSite cookie. Keep access and refresh tokens out of browser storage.
Protect a route
Check the product’s local role and Institution mapping, then the latest signed lifecycle projection. A successful central login alone is insufficient. On a revoked event or expired freshness, stop protected access and revoke local sessions and real-time connections. The Node example deliberately refuses product access until this adapter exists.
End a session
Local POST /logout must check origin or CSRF and clear the product session. The example also validates OIDC back-channel logout tokens for signature, issuer, audience, event, session ID, issue time, and replay ID. The Go issuer has an exact-session logout adapter and durable signed fanout implementation. Complete browser logout, real product delivery/acknowledgement and late-session refusal remain release gates. Test the complete path against your approved issuer and product before rollout.