Cryptographic identity infrastructure for AI agents.
Agent Passport gives an agent a stable public identity: who it is, which key it controls, who owns it, and whether it is still trusted. It combines a DID-backed registry, ownership claim flow, OAuth discovery, DPoP-bound tokens, and a browser dashboard for inspecting issued agent passports.
Agents are starting to act across tools, APIs, schedulers, sandboxes, and workflows. Without a first-class identity, every action looks like it came from the same human, API key, or service account.
That breaks attribution, permissioning, audit trails, delegation, and cross-tool trust.
Passport separates agent identity from credentials:
- Passport answers: who is this agent?
- Authsome answers: what can this agent access?
Together they let agents act on behalf of users without leaking credentials or collapsing every action into one shared service account.
- Registers agents by
did:keyidentity. - Assigns stable human-readable handles such as
swiftly-golden-fox. - Publishes public registry records and DID documents.
- Links agents to human owners through single-use claim tokens.
- Issues Ed25519-signed JWTs from a Passport server key.
- Binds every token to the agent key with OAuth DPoP.
- Exposes JWKS and OAuth discovery metadata for resource servers.
- Provides a dashboard, registry, passport view, claim page, and end-to-end auth demo.
Passport acts as an identity provider for agents.
- An agent generates an Ed25519 keypair locally.
- The public key is encoded as a W3C
did:keyidentifier. - The agent registers the DID with Passport and receives a stable handle.
- A human owner can claim the passport through an emailed magic link.
- The agent requests a challenge nonce and signs it with its private key.
- Passport verifies the signature and returns a JWT bound to that same key using
cnf.jkt. - The agent calls protected services with both
Authorization: Bearer <token>and a freshDPoPproof. - Resource servers verify the token through Passport's JWKS and verify proof-of-possession locally.
The full protocol writeup is in docs/passport-identity-whitepaper.md. A rendered copy is served at /passport-whitepaper.html.
| Concept | Meaning |
|---|---|
| DID | did:key:z... identifier derived from the agent's Ed25519 public key. |
| Handle | Stable public slug for lookup and display; survives future key rotation. |
| Passport record | Registry entry containing DID, handle, public key, status, owner, name, and description. |
| Claim flow | Optional owner verification flow that moves a passport from UNCLAIMED to CLAIMED. |
| DPoP | Per-request proof that the caller holds the private key bound to the token. |
| JWKS | Public server signing key endpoint used by resource servers to verify Passport-issued JWTs. |
UNCLAIMED -> CLAIMED
\-> REVOKED
UNCLAIMED: agent identity exists, but owner has not verified control.CLAIMED: owner has redeemed a single-use claim token.REVOKED: passport should no longer be trusted; auth requests are rejected.
| Method | Path | Purpose |
|---|---|---|
POST |
/auth/register |
Register a did:key identity and optional owner metadata. |
POST |
/auth/challenge |
Create a five-minute, single-use nonce for a DID. |
POST |
/auth/token |
Exchange signed nonce plus DPoP proof for a Passport JWT. |
POST |
/auth/claim |
Redeem a claim token and mark the passport CLAIMED. |
| Method | Path | Purpose |
|---|---|---|
GET |
/api/registry |
List registered passports. |
GET |
/registry/{handle} |
Fetch a public passport record with masked owner email. |
GET |
/registry/{handle}/did.json |
Fetch the agent's DID document. |
GET |
/passport/{handle} |
Browser passport view. |
| Method | Path | Purpose |
|---|---|---|
GET |
/me |
Verify Bearer token plus DPoP proof and return the authenticated agent identity. |
| Method | Path | Purpose |
|---|---|---|
GET |
/auth.md |
Human- and agent-readable authentication guide. |
GET |
/SKILL.md |
Agent-facing registration instructions. |
GET |
/.well-known/jwks.json |
Server public key for JWT verification. |
GET |
/.well-known/oauth-authorization-server |
OAuth authorization server metadata. |
GET |
/.well-known/oauth-protected-resource |
OAuth protected resource metadata. |
Install dependencies:
pnpm installCreate environment config:
cp .env.example .envRequired:
DATABASE_URL="postgresql://..."Optional:
NEXT_PUBLIC_BASE_URL="http://localhost:3000"
SERVER_PRIVATE_KEY="<base64-encoded-private-jwk>"
RESEND_API_KEY=""
EMAIL_FROM="Agent Passport <onboarding@example.com>"Notes:
DATABASE_URLshould point to Postgres. The project uses Prisma with the Neon adapter.SERVER_PRIVATE_KEYshould be set in persistent deployments. If omitted, the server creates an in-memory Ed25519 signing key on startup, which changes across restarts.RESEND_API_KEYenables emailed claim links. Without it, development logs print the claim link.
Apply database migrations:
pnpm exec prisma migrate devRun the app:
pnpm devOpen http://localhost:3000.
pnpm lint
pnpm test
pnpm build
pnpm db:generate
pnpm db:migrate:prodsrc/app/ Next.js App Router pages and route handlers
src/app/auth/ Registration, challenge, token, and claim endpoints
src/app/.well-known/ OAuth and JWKS discovery endpoints
src/lib/ DID, DPoP, JWT, crypto, email, Prisma, and handle utilities
src/components/ Dashboard, passport book, registration, claim, and demo UI
prisma/ Postgres schema and migrations
docs/ Protocol whitepaper
public/ Agent-readable guides and rendered whitepaper
The implemented product focuses on agent self-identity:
- DID-backed registration
- public registry lookup
- human ownership claim
- DPoP-bound token issuance
- JWKS-based verification
- protected-resource demo
The whitepaper also describes future delegation tokens using the RFC 8693 act claim. That delegation model is part of the protocol direction, but it is not implemented in this app yet.