chore(oidc): trace consent grant/gate decisions to diagnose the first-time consent loop (BUNYIP-234) #262

Merged
YousifShkara merged 1 commit from fix/BUNYIP-234-consent-loop-diagnostics into main 2026-06-29 06:00:21 +02:00
Owner

Diagnostic-only. The reported symptom (clicking Allow on /oauth2/consent leaves the user stuck on the same page; going back and re-clicking Mokosh works) is consistent with three possible root causes that the existing code-path tracing can't discriminate between:

  • Identity drift: the consent write keys on access_token.claims.sub via AuthenticatedUser; the authorize re-read keys on op_session.user_id. If those resolve to different user UUIDs for the same browser session, the write goes to row A and the read returns row B (empty).
  • Persistence visibility: provider.add_scopes_to_grant commits via provider.pool; the subsequent authorize call reads via the same pool. PG READ COMMITTED should make the write visible, but a multi-replica deploy or a connection-level snapshot would defeat that.
  • Scope-name mismatch: the union in add_scopes_to_grant could miss a scope if the requested vs persisted strings differ in case / whitespace.

Three targeted tracing::info lines:

  • consent_post (bunyip-web): logs the redirect target so we can confirm the user was actually sent back to /oauth2/authorize (and not, say, a loop within bunyip-web).
  • grant_consent (bunyip-api): logs the (user_id, client_id, scopes) the write is keyed on.
  • authorize consent gate (bunyip-oidc): logs the (user_id, client_id, requested_scopes, granted_scopes, missing) the gate decision uses.

Correlate the three by user_id across one repro and the root cause falls out:

  • user_id matches across all three but granted_scopes still empty -> persistence / visibility.
  • user_id differs between grant_consent and authorize -> identity drift.
  • granted_scopes includes the scope but missing still non-empty -> scope-name mismatch.

No behaviour change. Next session deploys, reproduces, reads logs, and ships the targeted fix from a known root cause.

#BUNYIP-234

Diagnostic-only. The reported symptom (clicking Allow on /oauth2/consent leaves the user stuck on the same page; going back and re-clicking Mokosh works) is consistent with three possible root causes that the existing code-path tracing can't discriminate between: - Identity drift: the consent write keys on access_token.claims.sub via AuthenticatedUser; the authorize re-read keys on op_session.user_id. If those resolve to different user UUIDs for the same browser session, the write goes to row A and the read returns row B (empty). - Persistence visibility: provider.add_scopes_to_grant commits via provider.pool; the subsequent authorize call reads via the same pool. PG READ COMMITTED should make the write visible, but a multi-replica deploy or a connection-level snapshot would defeat that. - Scope-name mismatch: the union in add_scopes_to_grant could miss a scope if the requested vs persisted strings differ in case / whitespace. Three targeted tracing::info lines: - consent_post (bunyip-web): logs the redirect target so we can confirm the user was actually sent back to /oauth2/authorize (and not, say, a loop within bunyip-web). - grant_consent (bunyip-api): logs the (user_id, client_id, scopes) the write is keyed on. - authorize consent gate (bunyip-oidc): logs the (user_id, client_id, requested_scopes, granted_scopes, missing) the gate decision uses. Correlate the three by user_id across one repro and the root cause falls out: - user_id matches across all three but granted_scopes still empty -> persistence / visibility. - user_id differs between grant_consent and authorize -> identity drift. - granted_scopes includes the scope but missing still non-empty -> scope-name mismatch. No behaviour change. Next session deploys, reproduces, reads logs, and ships the targeted fix from a known root cause. #BUNYIP-234
chore(oidc): trace consent grant/gate decisions to diagnose the first-time consent loop (BUNYIP-234)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 21s
Check / fmt + clippy + build + tests (pull_request) Successful in 9m24s
Create release / Create release from merged PR (pull_request) Has been skipped
2a7f693334
Diagnostic-only. The reported symptom (clicking Allow on /oauth2/consent leaves the user stuck on the same page; going back and re-clicking Mokosh works) is consistent with three possible root causes that the existing code-path tracing can't discriminate between:

- Identity drift: the consent write keys on access_token.claims.sub via AuthenticatedUser; the authorize re-read keys on op_session.user_id. If those resolve to different user UUIDs for the same browser session, the write goes to row A and the read returns row B (empty).
- Persistence visibility: provider.add_scopes_to_grant commits via provider.pool; the subsequent authorize call reads via the same pool. PG READ COMMITTED should make the write visible, but a multi-replica deploy or a connection-level snapshot would defeat that.
- Scope-name mismatch: the union in add_scopes_to_grant could miss a scope if the requested vs persisted strings differ in case / whitespace.

Three targeted tracing::info lines:

- consent_post (bunyip-web): logs the redirect target so we can confirm the user was actually sent back to /oauth2/authorize (and not, say, a loop within bunyip-web).
- grant_consent (bunyip-api): logs the (user_id, client_id, scopes) the write is keyed on.
- authorize consent gate (bunyip-oidc): logs the (user_id, client_id, requested_scopes, granted_scopes, missing) the gate decision uses.

Correlate the three by user_id across one repro and the root cause falls out:
- user_id matches across all three but granted_scopes still empty -> persistence / visibility.
- user_id differs between grant_consent and authorize -> identity drift.
- granted_scopes includes the scope but missing still non-empty -> scope-name mismatch.

No behaviour change. Next session deploys, reproduces, reads logs, and ships the targeted fix from a known root cause.

#BUNYIP-234
YousifShkara deleted branch fix/BUNYIP-234-consent-loop-diagnostics 2026-06-29 06:00:21 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/bunyip!262
No description provided.