fix(oauth): keep OIDC identity scopes when audience is requested #1

Merged
nhpro merged 1 commit from fix/oidc-scopes-with-audience into master 2026-05-19 13:56:08 +02:00
Owner

OIDC Core 1.0 §5.4 requires the standard scopes (openid, profile,
email, address, phone) and their conventional siblings (offline_access,
roles) to govern UserInfo claims independently of any audience
restriction. The /authorize handler was replacing the granted scopes
with the API-resource permission subset whenever audience was
present, leaving the access token with only resource permissions:
calls to /userinfo with that token then matched none of the
if scopeSet["profile"], if scopeSet["email"],
if scope == "roles" guards in OIDCClaims/enrichClaimsWithRoles
and returned {sub} — breaking every relying party that mixes
identity and API access in a single login.

Make the audience branch take the union of client-level scopes
(client.Scopes whitelist) and API resource permissions
(client_resource_permissions). RFC 8707 §2.1 still applies — the
audience binds the token to its target API — but the OIDC contract
on openid is preserved.

OIDC Core 1.0 §5.4 requires the standard scopes (openid, profile, email, address, phone) and their conventional siblings (offline_access, roles) to govern UserInfo claims independently of any audience restriction. The /authorize handler was replacing the granted scopes with the API-resource permission subset whenever `audience` was present, leaving the access token with only resource permissions: calls to /userinfo with that token then matched none of the `if scopeSet["profile"]`, `if scopeSet["email"]`, `if scope == "roles"` guards in OIDCClaims/enrichClaimsWithRoles and returned `{sub}` — breaking every relying party that mixes identity and API access in a single login. Make the audience branch take the union of client-level scopes (client.Scopes whitelist) and API resource permissions (client_resource_permissions). RFC 8707 §2.1 still applies — the audience binds the token to its target API — but the OIDC contract on `openid` is preserved.
fix(oauth): keep OIDC identity scopes when audience is requested
All checks were successful
Tests / test (pull_request) Successful in 57s
97e503acb5
OIDC Core 1.0 §5.4 requires the standard scopes (openid, profile,
email, address, phone) and their conventional siblings (offline_access,
roles) to govern UserInfo claims independently of any audience
restriction. The /authorize handler was replacing the granted scopes
with the API-resource permission subset whenever `audience` was
present, leaving the access token with only resource permissions:
calls to /userinfo with that token then matched none of the
`if scopeSet["profile"]`, `if scopeSet["email"]`,
`if scope == "roles"` guards in OIDCClaims/enrichClaimsWithRoles
and returned `{sub}` — breaking every relying party that mixes
identity and API access in a single login.

Make the audience branch take the union of client-level scopes
(client.Scopes whitelist) and API resource permissions
(client_resource_permissions). RFC 8707 §2.1 still applies — the
audience binds the token to its target API — but the OIDC contract
on `openid` is preserved.
nhpro merged commit 4d3bb1fac8 into master 2026-05-19 13:56:08 +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
nhpro/orion-auth-backend!1
No description provided.