Skip to content

ClientRegistration: gains scopes allow-list#17

Merged
sorah merged 1 commit into
mainfrom
scopes
Jun 1, 2026
Merged

ClientRegistration: gains scopes allow-list#17
sorah merged 1 commit into
mainfrom
scopes

Conversation

@sorah

@sorah sorah commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Requested scopes outside a client's recognised set are dropped before they reach the consent page or the grant, so a client cannot obtain or display scopes it was not configured for. openid and offline_access are always implicitly recognised; the per-client list only adds to those.

The DynamicClients and MetadataClients middlewares take a scopes option that is inherited by the client registrations they source.

🤖 Generated with Claude Code

Requested scopes outside a client's recognised set are dropped before
they reach the consent page or the grant, so a client cannot obtain or
display scopes it was not configured for. openid and offline_access are
always implicitly recognised; the per-client list only adds to those.

The DynamicClients and MetadataClients middlewares take a scopes option
that is inherited by the client registrations they source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sorah
sorah merged commit 6972542 into main Jun 1, 2026
2 checks passed
@sorah
sorah deleted the scopes branch June 1, 2026 07:14
sorah added a commit that referenced this pull request Jun 1, 2026
Follow-up to the per-client scopes allow-list (#17). The recognised
scopes of an authorization request were dropped once openid and
offline_access had been gated; retain them so authz rules can act on
them and operators can audit what was granted, on both the initial and
the refresh flow.

- AuthorizationCode gains a scopes member, serialized through as_json
  (round-trips storage) and as_log. Older records without the key
  deserialize to nil.
- DownstreamAuthorization exposes the recognised scopes to the rules as
  context.scopes (and carries them on its Result). requested_scopes is a
  required argument the caller always supplies from the appropriate
  source: the authorization endpoint passes the OIDC request's parsed
  scope (split the same way rack-oauth2 parses it downstream), the
  refresh flow the scopes recorded on the grant. The engine never reads
  the request for scopes; context.request stays purely a rule escape
  hatch. Either source is filtered through the client's allow-list, so a
  scope dropped from the client since issuance falls away on refresh.
- OidcAuthorizationEndpoint records the filtered scopes onto the
  AuthorizationCode it persists.
- RefreshToken gains a scopes member, minted from the AuthorizationCode
  and preserved across rotation; older records default to an empty set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant