feat!: delegated IdP, identity chaining, and capability-driven scope model#330
Open
feat!: delegated IdP, identity chaining, and capability-driven scope model#330
Conversation
…model
Redesign identity linking for multi-merchant agentic commerce.
Businesses can offer delegated identity providers, allowing buyers to
authenticate through a trusted IdP (e.g., Google, Shop) instead of
creating per-merchant accounts. Platforms can support these IdPs to
streamline identity linking — authenticate once, reuse across every
business that trusts the same provider.
## Delegated Identity Providers
Businesses declare trusted identity providers in config.providers,
keyed by reverse-domain identifier. Each provider specifies an auth_url
for metadata discovery (RFC 8414, OIDC fallback on 404). A business MAY
list itself as a provider, unifying business-hosted OAuth with delegated
auth under the same discovery mechanism.
## Identity Chaining (Accelerated IdP Flow)
When a platform already holds an IdP token, it chains the buyer's
identity to a new business without a browser redirect, per
draft-ietf-oauth-identity-chaining-08:
1. Platform requests a JWT authorization grant from the IdP (RFC 8693)
using the resource parameter
2. Platform presents the grant to the business (RFC 7523 jwt-bearer)
3. Business validates, resolves buyer identity, issues its own token
The IdP controls consent — it MUST NOT issue grants for businesses the
buyer has not authorized. Businesses MAY auto-provision accounts or
return a continue_url for buyer onboarding. Refresh tokens SHOULD NOT
be issued per the chaining draft §5.4. Two independent token lifecycles
with independent revocation.
## Capability-Driven Scope Model
Scopes define the permissions an identified buyer grants to a platform.
Declarations live centrally on the identity linking config, not on
individual capability schemas:
- config.capabilities map keyed by capability name declares which
capabilities offer buyer-scoped features
- required: true signals buyer identity is mandatory (identity_required
UCP business error if absent, with continue_url for onboarding)
- Sub-scopes use colon separator (e.g. dev.ucp.shopping.order:read),
defined by each capability spec as operation groups
- Scope tokens use capability names directly — no separate namespace
- Capabilities are never pruned from the intersection
- Platforms should request scopes incrementally
Three access levels: public (no auth), agent-authenticated (platform
credentials), buyer-authenticated (identity linking upgrades or gates
access depending on the business's required flag).
## Security
- PKCE MUST (platforms and businesses)
- iss validation MUST (RFC 9207, both sides)
- Exact redirect_uri matching MUST (businesses)
- scopes_supported MUST in RFC 8414 metadata
- 2-step discovery: RFC 8414 primary, OIDC fallback on 404 only
- JWT grants: 60s lifetime, jti single-use enforcement
- Strict abort on non-404 discovery errors
|
Thanks @igrigorik. Agree with the changes. Great addition to UCP! |
aglazer
approved these changes
Apr 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Redesign identity linking for multi-merchant agentic commerce. Businesses can offer delegated identity providers, allowing buyers to authenticate through a trusted IdP (e.g., Google, Shop) instead of creating a per-merchant account. Platforms can support these IdPs to streamline identity linking — authenticate once, reuse across businesses that trusts the same provider.
This PR carries builds on / supersedes #265, reverted in #329.
Delegated Identity Providers
The current identity linking spec assumes 1:1 — each business operates its own OAuth authorization server, requiring a full OAuth dance per merchant. In agentic commerce, where platforms shop across many businesses on a buyer's behalf, this means N merchants = N handoffs.
Businesses can now declare trusted identity providers in
config.providers, keyed by reverse-domain identifier:Here the business trusts Google as an external IdP and also lists itself (
com.example.merchant) for business-hosted OAuth — both use the same discovery mechanism. Each provider'sauth_urlis resolved via RFC 8414, with OIDC/.well-known/openid-configurationfallback on 404.Two distinct flows:
Identity chaining
The accelerated flow implements a two-phase pattern:
resourceparameter to identify the target businessThe IdP controls consent — it MUST NOT issue grants for businesses the buyer has not authorized. Businesses MAY auto-provision accounts or return a
continue_urlfor buyer onboarding (terms acceptance, etc.). Two independent token lifecycles with independent revocation. Refresh tokens SHOULD NOT be issued per the chaining draft.Capability-driven scope model
Scopes define the permissions an identified buyer grants to a platform within a capability. Unlike #265's approach of annotating individual capability schemas with
identity_scopes, scope declarations live centrally on the identity linking config. This is because whether a capability requires buyer auth is a business decision — a B2B wholesaler gates catalog access, a B2C retailer serves it publicly.Three access levels
Identity linking upgrades capabilities to buyer-authenticated access. Capabilities are never pruned from the intersection based on identity linking; there is no capability pruning algorithm.
Config shape
Building on the provider example, businesses declare which capabilities offer buyer-scoped features alongside their trusted IdPs:
required: accessible without buyer auth, identity upgrades the experiencerequired: true: business returnsidentity_requirederror without buyer identityscopes: sub-scope operation groups defined by each capability's spec, joined with colon on the wire (e.g.,dev.ucp.shopping.order:read)Carried forward from #265
issvalidation MUST (RFC 9207, both sides)redirect_urimatching MUST (businesses)scopes_supportedMUST in RFC 8414 metadatajtisingle-use enforcementType of change
functionality to not work as expected, including removal of schema files
or fields)
!to my PR title (e.g.,feat!: remove field).Checklist