Skip to content

Identity 2/n: signed user-info claims - #339

Open
raubrey-stripe wants to merge 22 commits into
mainfrom
raubrey/aap-credential-wallet
Open

raubrey-stripe wants to merge 22 commits into
mainfrom
raubrey/aap-credential-wallet

Conversation

@raubrey-stripe

@raubrey-stripe raubrey-stripe commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

This PR prepares the second step in our identity work: exposing cryptographically signed user-info claims like name, email, and phone.

A link wallet user/client/agent can present these signed claims to a downstream verifier (like an MPP service verifying incoming requests) and the verifier can derive two interesting properties from this:

  1. The verifier can know that Link issued this claims because the claims are signed by Link's private issuer key
  2. The verifier can know that only the intended recipient of these signed claims is the one presenting thembecause the claims are signed again, this time by the client's private key (not included in this PR)

Change here include

  • Uses the new api.link.com/credential endpoint
  • Passes up a the client public key cnf.jwt
  • Returned is the selective disclosure JWT (fancy "wallet" of these signed claims, SD+JWT)
  • This SD+JWT is signed by Link's private issuer key, which can be validated against the public key available at https://api.link.com/.well-known/aap-issuer
  • (Not included in this PR, but when the credentials are presented to a verifier they get signed by the client's private key in a new "bound" JWT)
  • (Also fixing some issues found in attestations command - namely human output)

Similar to #331, this credential/signed claims functionality is not yet exposed externally and is gated behind a flag in the cli itself to hide it from agents while we prepare for rollout.

raubrey-stripe and others added 18 commits September 17, 2026 09:45
Provision SD-JWT credentials through the issuer's discovered credential endpoint while keeping private holder keys local to the CLI.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Avoid breaking unrelated SDK resources when local HTTP API overrides are configured; enforce AAP issuer constraints only when credential issuance begins.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Use AAP_ACCESS_TOKEN only for attestation minting while credential issuance follows its documented flag-or-stored-session authentication path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Credential issuance no longer requires aap:represent, so document only the remaining user and payment-method scopes.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Rename issuer-origin helpers and describe discovery without the protocol acronym. Keep the well-known metadata path as a wire identifier.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Same discovery gate as attestations: register only when opted in, and keep the command out of MCP tool lists.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Use `identity credentials get` and describe it as signed user info from Link rather than SD-JWT terminology.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>
Allow identity credentials get to take a public JWK without reading or creating a local private key, and return a portable artifact that distinguishes managed vs external holder ownership.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Match the attestations factory so TypeScript 7 accepts the cached ICredentialsResource return.

Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
Committed-By-Agent: cursor
@raubrey-stripe
raubrey-stripe marked this pull request as ready for review September 17, 2026 16:57
@raubrey-stripe
raubrey-stripe requested a review from a team as a code owner September 17, 2026 16:57

@drapeau-stripe drapeau-stripe left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 comments for your agent (Handle concurrent first-time holder-key creation can be done in a followup if you prefer). The other one was already flagged in slack for you by @staubman-stripe . I had my agent take a stab at implementing a solution and testing it, ff to use that comment/context (or draft your own).

Otherwise, everything else tracks and looks correct/verifies in my local tests.

Comment thread packages/cli/src/commands/credentials/holder-key.ts
Comment thread packages/cli/src/commands/credentials/index.tsx
raubrey-stripe and others added 3 commits September 17, 2026 21:46
Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>
Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>
Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.com>
Comment thread skills/use-link-identity/SKILL.md Outdated
Comment thread packages/cli/src/commands/credentials/storage.ts
Committed-By-Agent: codex
Co-authored-by: codex <noreply@openai.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.

3 participants