# 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. ```sh 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. | ```sh 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: ```json {"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: ```sh 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.