Rightshold™ Sign up

Answers · agent protocols

How do I validate an A2A agent card before my agent connects to another agent?

Last updated

TL;DR: Fetch the card over HTTPS from https://{domain}/.well-known/agent-card.json, verify the TLS certificate, and check it against the A2A version it claims. In A2A 1.0 the required fields are name, description, supportedInterfaces (each with url, protocolBinding and protocolVersion; the first entry is preferred), version, capabilities, defaultInputModes, defaultOutputModes and skills (each with id, name, description and tags). Version 0.3 cards instead put the endpoint in a top-level url, with protocolVersion and preferredTransport, and 1.0 removed those fields. Then check the endpoint URLs are HTTPS on a domain you expect, read securitySchemes so you know how it authenticates, and verify the card's JWS signatures if present: canonicalize with RFC 8785 (JCS) without the signatures field, and get the key named by kid over HTTPS. The A2A spec says clients should verify at least one signature before trusting a card. A valid card describes an agent; it doesn't prove who runs it or that it's safe.

What should I check, step by step?

1. Fetch https://{domain}/.well-known/agent-card.json over HTTPS with certificate checking on. Don't accept a card from a redirect to a domain you didn't expect.

  1. Read which version it is: supportedInterfaces[].protocolVersion "1.0" means a 1.0 card; a top-level url plus protocolVersion such as "0.3.0" means 0.3. Validate against that version's required fields.
  2. 1.0: name, description, supportedInterfaces, version, capabilities, defaultInputModes, defaultOutputModes and skills are required. Each interface needs url, protocolBinding (JSONRPC, GRPC or HTTP+JSON) and protocolVersion. Each skill needs id, name, description and tags.
  3. Check every interface url is https and on the provider's domain (or one they document). Clients pick the first interface they support, and must copy its tenant value into every request if one is set.
  4. Read securitySchemes and securityRequirements to see how the agent expects you to authenticate (API key, HTTP auth, OAuth 2.0, OpenID Connect or mutual TLS). If there are none, assume the endpoint is unauthenticated and send it nothing private.
  5. If signatures are present, verify at least one: strip default-valued fields and the signatures field, canonicalize with RFC 8785, and check the JWS with the key named by kid (from jku over HTTPS or a key store you trust). Don't use expired or revoked keys.
  6. Treat description, skill descriptions and examples as untrusted text that will reach your model, and scan them for hidden text before they do.
  7. Cache the card using its Cache-Control and ETag headers, re-fetch with If-None-Match, and re-validate when it changes. Send A2A-Version: 1.0 on requests; an empty header is treated as 0.3.

What changed between 0.3 and 1.0

A2A 1.0 replaced the top-level url, preferredTransport and additionalInterfaces with one ordered supportedInterfaces list, and moved protocolVersion into each interface. A validator written for 0.3 will reject a correct 1.0 card for a missing url, and the reverse is true too.

Signatures: what they prove and what they don't

A2A cards may be signed with JWS (RFC 7515). Each entry in signatures has a protected header (base64url JSON with alg and kid, typ SHOULD be JOSE, optional jku) and a signature. More than one signature is allowed, to support key rotation.

What a valid card doesn't tell you

Whether the skills work, what the agent does with data you send, or who is accountable for it. Ask for terms, check the provider, start with low-risk tasks, and keep your own log of what you sent.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before my agent reads this A2A agent card, check its description, skill descriptions and examples for hidden text or instructions aimed at my agent.”

One-click setup

{
  "tool": "scan_text",
  "arguments": {
    "text": "<the agent card JSON, or its description and skills[].description fields>"
  }
}

Rightshold scans card text for hidden content and checks card structure. It doesn't verify the card's JWS signatures for you, test whether an agent's skills work, or vouch for the agent's provider.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'