fix(oidc): re-validate tenant assignment on refresh rotation (BUNYIP-200) #241

Merged
Claude-Run merged 1 commit from fix/bunyip-200-revalidate-tenant-on-refresh-rotation into main 2026-06-26 05:18:10 +02:00
Member

Refresh-token rotation copied the original /authorize selected_tenant_id onto every new token in the family and never re-checked it, so an at+jwt kept minting a stale tenant claim even after an admin revoked the user's tenant assignment.

handle_refresh_grant now mirrors the existing has_entitlement re-check: for a client whose tenant_claim_name IS NOT NULL it re-runs OAuthClientUserTenantRepository::assignments_for and rejects with invalid_grant (forcing a fresh /authorize) when the carried selected_tenant_id is no longer among the user's current assignments.

The admin tenant assign/unassign endpoints now revoke the affected user's OIDC refresh-token families for that client (new TokenRepository::revoke_client_user_refresh_tokens) so outstanding tokens cannot keep rotating the stale claim. unassign returns the deleted row so the handler knows the affected (user, tenant).

#BUNYIP-200

Refresh-token rotation copied the original /authorize selected_tenant_id onto every new token in the family and never re-checked it, so an at+jwt kept minting a stale tenant claim even after an admin revoked the user's tenant assignment. handle_refresh_grant now mirrors the existing has_entitlement re-check: for a client whose tenant_claim_name IS NOT NULL it re-runs OAuthClientUserTenantRepository::assignments_for and rejects with invalid_grant (forcing a fresh /authorize) when the carried selected_tenant_id is no longer among the user's current assignments. The admin tenant assign/unassign endpoints now revoke the affected user's OIDC refresh-token families for that client (new TokenRepository::revoke_client_user_refresh_tokens) so outstanding tokens cannot keep rotating the stale claim. unassign returns the deleted row so the handler knows the affected (user, tenant). #BUNYIP-200
fix(oidc): re-validate tenant assignment on refresh rotation (BUNYIP-200)
All checks were successful
E2E / Playwright against deployment (pull_request) Successful in 23s
Check / fmt + clippy + build + tests (pull_request) Successful in 9m14s
Create release / Create release from merged PR (pull_request) Has been skipped
736cd77dfa
Refresh-token rotation copied the original /authorize selected_tenant_id onto every new token in the family and never re-checked it, so an at+jwt kept minting a stale tenant claim even after an admin revoked the user's tenant assignment.

handle_refresh_grant now mirrors the existing has_entitlement re-check: for a client whose tenant_claim_name IS NOT NULL it re-runs OAuthClientUserTenantRepository::assignments_for and rejects with invalid_grant (forcing a fresh /authorize) when the carried selected_tenant_id is no longer among the user's current assignments.

The admin tenant assign/unassign endpoints now revoke the affected user's OIDC refresh-token families for that client (new TokenRepository::revoke_client_user_refresh_tokens) so outstanding tokens cannot keep rotating the stale claim. unassign returns the deleted row so the handler knows the affected (user, tenant).

#BUNYIP-200
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!241
No description provided.