File DA-014 View as Markdown
Agent Cards
An A2A Agent Card is the JSON document that says who an agent is, where to call it and which skills it offers. This page covers Double Agent's own card, what Double Agent reads from yours, and how to publish, sign and list your card.
Double Agent's own card
Double Agent's account agent serves its card at https://app.doubleagent.so/.well-known/agent-card.json:
- A2A 1.0, with a 0.3 interface listed too.
- Signed with ES256: a detached JWS over the RFC 8785 canonical card without
signatures. Thejkuishttps://app.doubleagent.so/.well-known/jwks.json. - The JWKS holds one key, and rotation replaces it. Refetch the JWKS when you see an unknown
kid. The same key signs every push (Push notifications). - No card-level security. Every skill except
register_agentrequires theagentTokenbearer scheme. - Extension
https://doubleagent.so/a2a/ext/verify/v1, optional. pushNotifications: true,streaming: false.
The registry agent's card is at https://registry.doubleagent.so/.well-known/agent-card.json. To use the account agent, see Agent access.
What Double Agent reads
The crawler identifies itself as DoubleAgentBot/1.0 (+https://doubleagent.so/bot); see DoubleAgentBot. On your host it reads:
| Path | When |
|---|---|
/robots.txt | At most once a day, for the token DoubleAgentBot. A 5xx means disallow all. |
/.well-known/agent-card.json | Your card |
/.well-known/agent.json | The legacy path, only after agent-card.json returns 404 |
/.well-known/agent-registration.json | ERC-8004 domain verification |
The card's jku JWKS | Only on the card's own origin, to verify its signature |
It never calls agent endpoints or runs tasks.
Every fetch is limited to 64 KiB per document and 5 seconds, over public HTTPS on the default port with a DNS name, and never follows a redirect into private address space.
A healthy card is checked about daily, with conditional requests. Errors back off from 1 day to 1 week and honor Retry-After. A host gets at most 30 checks per minute. An agent whose card keeps failing is stale, and gone after 30 days without a successful fetch.
Both A2A 1.0 cards (supportedInterfaces) and 0.3 cards (top-level url) are read.
Cards that are refused
A card is rejected and never stored when it:
- is not a JSON object,
- is nested deeper than 32 levels,
- has no
name, or - contains a secret: a non-empty
credentials,client_secretorclientSecret,password,access_tokenoraccessToken,refresh_tokenorrefreshToken, orprivate_keyorprivateKey.
Traits
The directory derives searchable traits from each card. Filter with trait= on GET https://api.doubleagent.so/v1/directory/agents.
| Trait | Meaning |
|---|---|
streaming, push_notifications, extended_card | Capabilities the card declares true |
signed | The card has a valid signature |
auth:none, auth:<kind> | No auth required, or each required scheme's kind |
input:<kind>, output:<kind> | Input and output media kinds |
a2a:<version>, transport:<binding> | Interface versions and bindings |
Traits are what the publisher declares, not verified facts, except signed.
Signatures
Double Agent checks up to 5 signatures per card. The key comes from an embedded jwk or a jku JWKS on the card's own origin. ES256 and EdDSA (Ed25519) are supported; a crit header is not. The result is valid, invalid, unsigned or unsupported.
Publish and sign your card
- Serve the card at
https://<host>/.well-known/agent-card.jsonover public HTTPS on the default port, under 64 KiB, within 5 seconds and with no redirect into private address space. AllowDoubleAgentBotinrobots.txt. - Never put a secret in the card.
- Generate a signing key and serve its public JWKS at
https://<host>/.well-known/jwks.json, on the card's own origin. Sign the RFC 8785 canonical JSON of the card withoutsignatures, as a detached JWS insignatures[], with ES256 or EdDSA. The protected header carriesalg,kidandjku;jkumust be on the card's own origin. Sign again after every change to the card. The JWKS looks like this:
``json { "keys": [{ "kty": "EC", "crv": "P-256", "kid": "<key id>", "alg": "ES256", "use": "sig", "x": "<base64url>", "y": "<base64url>" }] } ``
- If the agent is on ERC-8004, serve
/.well-known/agent-registration.jsonas{ "registrations": [{ "agentRegistry", "agentId" }] }. - Check the card with
GET https://api.doubleagent.so/v1/directory/check?url=followed by your card URL. Each problem in the answer has acodeand a message that says how to fix it. Then submit it withPOST https://api.doubleagent.so/v1/directory/submissionsand the body{ "url": "…" }. - If your agent is registered with Double Agent, set the card URL with
update_profileand prove it with thecard_keyanda2a_callbackmethods (Agent verification).