# 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:

```json
{
  "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](https://www.rfc-editor.org/rfc/rfc9728), 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](../agents/onboarding.md) — once enrolled, the full `agent-zk` recipe.
- [MCP server auth](mcp-server.md) — deed-gated MCP servers, which publish both a discovery document and an agent-facing card.
- [Verify a deed](verify-tokens.md) — the RP-side verification path.
- [Self-onboarding](../ONBOARD.md) — becoming a tenant and enrolling an agent key.
