feat!: replace identity linking with full identity management capability#337
feat!: replace identity linking with full identity management capability#337sinhanurag wants to merge 6 commits intoUniversal-Commerce-Protocol:mainfrom
Conversation
igrigorik
left a comment
There was a problem hiding this comment.
@sinhanurag — thanks for putting this together. I want to flag an architecture concern before this goes further, because I think the CRUD operations are valuable but sitting on the wrong foundation.
Identity linking and identity management are different layers
This PR replaces identity_linking with identity_management, absorbing the linking flow as one operation (link_identity). But linking and management answer different questions:
- Identity linking = authorization primitive. How does a platform obtain buyer-authenticated access to a business's capabilities? The output is a scoped token. The protocol deals in trust relationships, scopes, and token lifecycles — not profile data.
- Identity management = resource CRUD. How does a platform read and write buyer profile data at a business? This consumes the authorization that linking provides.
Identity profile CRUD should be a separate capability that operates alongside identity linking, not a replacement for it:
dev.ucp.common.identity_linking → authorization (how you get a buyer token)
dev.ucp.common.identity_profile → resource CRUD (what you do with it)
A business can offer identity linking without profile CRUD (most will — they just want scoped access tokens). Businesses that do want platforms to manage profiles declare identity_profile as an additional capability. The capability intersection handles the advertisement — if the business declares it, platforms know it's available.
Separately, on operations...
link_identity: belongs on identity linking, not here
The token exchange flow, JWT validation, trust model, and security requirements are specified in the identity linking capability (#354 + #330). Putting a link_identity operation here without that security model creates an unspecified endpoint that does the most security-sensitive thing in the protocol.
list_identities: do we need this?
This feels odd. Yes a buyer may have multiple accounts, but those are distinct identities, you don't typically list / branch at this layer -- each one has separate set of tokens, etc.
create_identity
I'm picturing the flow as....
- Agent discovers business supports identity_linking + identity_profile
- Agent attempts identity chaining → business: "no account"
- Agent calls create on identity_profile (agent-auth, no buyer token)
- Agent retries chaining → business resolves buyer → issues token
- Agent uses buyer-authenticated token for read, update, checkout, etc.
On step 3 --> 4: when the agent retries chaining after creating the profile, the business matches the JWT grant's claims against the profile (e.g., email from the IdP maps to the email submitted during create). This keeps create as pure profile CRUD — no awareness of the linking model needed.
Not every business will accept/allow create - e.g., a B2B wholesaler that vets customers won't expose a create endpoint. Businesses that want programmatic provisioning declare identity_profile. Those that don't simply don't declare it — the default path remains auto-provisioning or continue_url during the linking flow.
Description
This PR introduces the
dev.ucp.common.identity_managementcapability to the Universal Commerce Protocol (UCP) specification, replacing the legacydev.ucp.common.identity_linkingcapability. This change expands the protocol to support a full identity lifecycle, including creation, retrieval, updates, and deletion, in addition to the existing OAuth-based identity linking flow.Summary of changes:
Documentation:
identity-management.mddetailing the new capability and operations.identity-management-rest.mdandidentity-management-mcp.mdfor transport-specific bindings.identity-linking.md(content absorbed and expanded inidentity-management.md).overview.mdto reference the new capability identifier.Schemas:
source/schemas/common/types/identity.jsondefining the base user identity profile.API Definitions:
/identitiesand/identities/{id}endpoints tosource/services/common/rest.openapi.json.create_identity,get_identity,update_identity, anddelete_identityoperations tosource/services/common/mcp.openrpc.json.Motivation and Context:
The previous specification only supported linking existing identities. To support a complete commerce experience, platforms and businesses need to manage the full lifecycle of a user's identity. This PR establishes that foundation.
Type of change
Please delete options that are not relevant.
functionality to not work as expected, including removal of schema files
or fields)
Is this a Breaking Change or Removal?
If you checked "Breaking change" above, or if you are removing any schema
files or fields:
!to my PR title (e.g.,feat!: remove field).Breaking Changes / Removal Justification
The removal of
identity-linking.mdand the replacement of thedev.ucp.common.identity_linkingcapability withdev.ucp.common.identity_managementconstitutes a breaking change for the specification. While the core OAuth flow is preserved under the new capability, the change in the capability identifier and the reorganization of the documentation files require this to be flagged as a breaking change to ensure implementers update their references.Checklist
Pull Request Title
This repository enforces Conventional Commits. Your PR title must follow
this format:
type: descriptionortype!: descriptionfor breaking changes.Types:
feat: A new featurefix: A bug fixdocs: Documentation only changesstyle: Changes that do not affect the meaning of the code (white-space,formatting, etc)
refactor: A code change that neither fixes a bug nor adds a featureperf: A code change that improves performancetest: Adding missing tests or correcting existing testschore: Changes to the build process or auxiliary tools and librariesBreaking Changes:
If your change is a breaking change (e.g., removing a field or file), you
must add
!before the colon in your title:type!: descriptionExamples:
feat: add new payment gatewayfix: resolve crash on checkoutdocs: update setup guidefeat!: remove deprecated buyer field from checkout