Agent-to-agent cards#
An agent card is metadata a service publishes to let other agents discover its authentication requirements and capabilities. Instead of a human reading a documentation page and configuring their client, an agent reads the card, sees what's needed, and acts — no human in the loop.
By the A2A convention, a resource publishes its card at /.well-known/agent.json, relative to its own base URL — the same well-known-path pattern RFC 9728 and Grantor's discovery document use. Publish yours there so a consuming agent (or an off-the-shelf A2A client) can find it without being told the URL out of band.
When a Grantor-gated resource refuses a caller with a 401, the response funnel includes discovery — the URL where that resource publishes its deed requirements. An agent card is the inverse: a pre-flight contract, published before authentication is attempted, telling an agent what it requires before it ever gets a 401. A card declaring securitySchemes with a Grantor deed requirement points at that same discovery URL, which names the deed mode, challenge endpoint, chain, and tenant.
Fragment 1: Agent card deed declaration#
An agent card's securitySchemes field names the deed scheme and links to the resource's discovery document:
{
"name": "Acme API",
"description": "An example resource gated with Grantor deeds",
"version": "1.0.0",
"baseUrl": "https://api.example.com",
"securitySchemes": {
"grantor-deed": {
"type": "http",
"scheme": "Grantor-Deed",
"description": "Grantor deed (zero-knowledge or wallet-signed)",
"discovery": "/.well-known/grantor-deed",
"learn": "https://chaingrantor.com/.well-known/grantor-onboard.json"
}
},
"security": [
{ "grantor-deed": [] }
]
}
The discovery path is relative to this resource's baseUrl (https://api.example.com/.well-known/grantor-deed here). The learn URL is stable and global — the same for every Grantor-gated resource, pointing at the onboarding manifest so an agent new to Grantor knows where to start.
Fragment 2: Consuming-agent recipe#
An agent fetches the card from /.well-known/agent.json, sees the grantor-deed scheme, and follows this recipe:
0. Fetch the agent card (if not already fetched):
GET https://api.example.com/.well-known/agent.json
→ { "securitySchemes": { "grantor-deed": { "discovery": "/.well-known/grantor-deed", … } }, … }
1. Fetch the discovery document:
GET https://api.example.com/.well-known/grantor-deed
→ { "tenant": 1, "audience": "api.example.com", "challenge_endpoint": "/auth/challenge", "modes": ["user-sig", "agent-zk"], "chain": { "id": 8453, "registry": "0x…" }, "origin_vouch": { … } }
2. Fetch a challenge from the endpoint named in the discovery document:
GET https://api.example.com/auth/challenge
→ { "challenge": "abc123def…" }
3. Mint a deed. For agent-zk (fleet membership):
- Verify the origin vouch against the origin you are talking to (https://api.example.com).
- Build a Semaphore membership proof of this tenant's on-chain agent tree.
- Mint the deed with the proof and the challenge.
Result: { "mode": "agent-zk", "proof": "…", "challenge": "…", … }
4. Present the deed and challenge in separate headers:
POST https://api.example.com/auth/token
X-Grantor-Deed: <base64url-encoded deed JSON>
X-Grantor-Challenge: abc123def…
→ { "access_token": "…" } (the resource's own session bearer)
The deed (X-Grantor-Deed header) and challenge are always separate — never read the challenge from inside the deed, which would let an attacker pick its own nonce and break the single-use property.
The learn URL points an agent that is not yet a tenant to the onboarding flow: the chain, funding, tier fees, and contract calls to become a tenant and enroll an agent key.
Bridge to RFC 9728#
This agent-card scheme serves the same discovery purpose as RFC 9728 OAuth 2.0 Protected Resource Metadata, which a resource publishes at /.well-known/oauth-protected-resource for off-the-shelf OAuth clients. An MCP-spec client that speaks OAuth 2.0 uses the RFC 9728 path; an agent following this pattern uses the card. Both point at the same discovery document (same tenant, audience, challenge_endpoint, modes, chain, origin_vouch).
See also#
- Agent onboarding — once enrolled, the full
agent-zkrecipe. - MCP server auth — deed-gated MCP servers, which publish both a discovery document and an agent-facing card.
- Verify a deed — the RP-side verification path.
- Self-onboarding — becoming a tenant and enrolling an agent key.