coulomb-social/docs/release/oidc-userinfo-binding-review-2026-10-30.md
tegwick 5639603231
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m44s
Bind optional UserInfo to verified OIDC identity claims
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
2026-10-30 23:11:18 +01:00

3.2 KiB

Bind UserInfo to the verified sign-in identity

WP-0015-T04 source correction. No native issuer reset, LDAP password change, production deployment or new productive acceptance is claimed. UC-009 retains its existing personal acceptance and remains an unestablished automated journey. The sealed storage proposal and its candidate image are unchanged; this source correction requires a subsequent reviewed release before productive use.

The callback previously merged arbitrary UserInfo values over verified ID-token claims and accepted a token-response userinfo object when no ID token existed. Signed-token callback reproductions demonstrated that a mismatched UserInfo subject could establish a session, and a matching subject with altered issuer could create a member under that replacement issuer. Seven of eight initial reproduction cases failed before the fix; the valid-token/no-UserInfo case passed. These are isolated reproductions, not evidence that production has been exploited.

The assembler now requires an ID token and the existing signature/issuer/audience/ expiry validation. Nonempty UserInfo must carry exactly the same string subject. It may update only the three profile fields used by this app: name, email and preferred username. Identity, tenant, client binding, groups/roles and assurance remain the signed token's assertions. UserInfo cannot satisfy a requested AAL2 step-up over an AAL1 token. An unavailable/401 UserInfo endpoint still allows login from a valid signed token, preserving the existing accepted fallback.

OpenID Connect Core §5.3.2 requires exact subject equality before UserInfo values are used. The profile-only merge is the app's stricter IAM boundary, preserving its verified provenance. KeyCape's inspected owner implementation returns its canonical token subject and profile information from UserInfo; no provider modification is needed here.

tests/test_oidc_userinfo_binding.py uses ephemeral RSA keys and actual JWT/JWKS verification in the real Django callback. Only the code exchange and HTTP peer are synthetic; every HTTP request must name an exact fixture endpoint. No socket, real account, credential, reset URL or production provider is used. Thirteen cases cover mismatched/missing/non-string subjects, absent/empty/non-string ID tokens, profile enrichment with conflicting authority values, optional UserInfo absence, step-up refusal and valid UserInfo failing to rescue wrong issuer/audience, expired tokens or an empty signed subject. Rejection creates neither Member nor authenticated session and consumes the callback state. Existing profile-enrichment test data now includes the provider-required subject.

Twenty focused identity tests and all 396 full make check cases pass, with zero failures or skips and mandatory browser journeys included. The companion JSON records the gate, source/test hashes and explicit execution boundaries. UC-009's registry links the new callback checks without promoting the journey or changing its accepted contract. The complete isolated native reset→directory→inbox→app browser journey, native release and owner/productive review remain open on WP-0015-T04.