Agent Discovery and the Agent Card

The Agent Card is a JSON metadata document that an A2A server publishes to describe its identity, capabilities, skills, service endpoints, and authentication requirements. Clients use it to discover suitable agents and configure interactions. What follows is organized from chapter 8 of the specification. For the field definitions, see Data Structures ; for a practical discussion of discovery strategies, see Agent Discovery .

Publication and discovery mechanisms

An A2A server MUST make an Agent Card available. Clients can find it through:

MechanismDescription
Well-Known URIRequest https://{server_domain}/.well-known/agent-card.json, which is also the default endpoint for the public card in the Python SDK
Registries and catalogsQuery curated catalogs of agents
Direct configurationUse a pre-configured Agent Card URL or content

Declaring protocols: supportedInterfaces

The Agent Card MUST declare the supported protocols correctly:

  • supportedInterfaces SHOULD declare all supported protocol combinations in preference order, and the first entry is the preferred interface.
  • Each interface MUST accurately declare its transport protocol (protocolBinding), protocol version (protocolVersion), and URL. A URL MAY be reused when several transports are available at the same endpoint.
  • Clients MUST select as follows: parse supportedInterfaces and pick the first supported transport; prefer earlier entries when several options are supported; and use the URL that belongs to the selected transport.
  • Clients MUST set the tenant field in every request message to exactly the value declared in the selected AgentInterface entry, and MUST omit the field if that entry does not set tenant. For how multi-tenant deployments work, see Multi-Tenancy .

A minimal Agent Card that declares three bindings (adapted from the official specification):

{
  "name": "Example Agent",
  "description": "An example agent that echoes messages.",
  "supportedInterfaces": [
    {"url": "https://example.com/a2a/v1", "protocolBinding": "JSONRPC", "protocolVersion": "1.0"},
    {"url": "https://example.com/a2a/grpc", "protocolBinding": "GRPC", "protocolVersion": "1.0"},
    {"url": "https://example.com/a2a/json", "protocolBinding": "HTTP+JSON", "protocolVersion": "1.0"}
  ],
  "version": "1.0.0",
  "capabilities": {
    "streaming": true,
    "pushNotifications": false,
    "extendedAgentCard": false
  },
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"],
  "skills": [
    {
      "id": "echo",
      "name": "Echo",
      "description": "Echoes the input.",
      "tags": ["echo"]
    }
  ]
}

Agent Card signing

Agent Cards MAY be digitally signed with JSON Web Signature (JWS, RFC 7515 ) to ensure authenticity and integrity: clients can verify that a card has not been tampered with and comes from the claimed provider.

Canonicalization

Before signing, the card content MUST be canonicalized with the JSON Canonicalization Scheme (JCS, RFC 8785 ), so that signatures are generated and verified consistently across JSON implementations. Before canonicalization, the proto field presence semantics apply:

  • optional fields that were not explicitly set MUST be omitted from the JSON object.
  • optional fields that were explicitly set, even to a default value, MUST be included.
  • Fields marked REQUIRED MUST always be present.
  • Fields with default values MUST be omitted unless the field is REQUIRED or has the optional keyword.
  • Object properties are ordered lexicographically by key, and primitive values such as numbers and strings follow the consistent RFC 8785 representation.

Signature format

A signature is an AgentCardSignature object whose three fields represent the JWS components:

FieldDescription
protectedRequired. The base64url-encoded JWS protected header (a JSON object)
signatureRequired. The base64url-encoded signature value
headerOptional. The unprotected header (a JSON object, not base64url-encoded)

The protected header MUST include alg (the signing algorithm, such as ES256 or RS256), typ (SHOULD be JOSE), and kid (the key ID), and MAY include jku (a URL to a JWKS that contains the public key). For example:

{"alg":"ES256","typ":"JOSE","kid":"key-1","jku":"https://example.com/agent/jwks.json"}

The steps to generate a signature:

  1. Prepare the payload: remove properties with default values, exclude the signatures field, and canonicalize the result with RFC 8785.
  2. Construct the protected header and base64url-encode it to produce protected.
  3. Compute the signing input ASCII(BASE64URL(UTF8(protected header)) || '.' || BASE64URL(payload)), sign it with the algorithm named by alg and the private key, and base64url-encode the result to produce signature.
  4. Assemble the AgentCardSignature, optionally adding an unprotected header.

Signature verification

A client that verifies signatures MUST:

  1. Extract the signature from the signatures array.
  2. Retrieve the public key using kid and jku, or from a trusted key store.
  3. Remove properties with default values from the received card and exclude the signatures field.
  4. Canonicalize the result using RFC 8785.
  5. Verify the signature against the canonicalized payload.

Security considerations: clients SHOULD verify at least one signature before trusting a card; public keys SHOULD be retrieved over secure channels such as HTTPS; clients MAY maintain a trusted key store for known providers; expired or revoked keys MUST NOT be used for verification; and multiple signatures MAY be present to support key rotation.

Caching

Agent Card content changes far less often than clients may fetch it, so servers and clients SHOULD use standard HTTP caching to reduce unnecessary network overhead.

Servers:

  • Agent Card HTTP endpoints SHOULD return a Cache-Control header with a max-age suited to the agent’s expected update frequency.
  • They SHOULD return an ETag derived from the card’s version field or a hash of the card content.
  • They MAY return Last-Modified.

Clients:

  • SHOULD honor the HTTP caching semantics defined in RFC 9111 .
  • When a cached card has expired, SHOULD use conditional requests (If-None-Match with the stored ETag, or If-Modified-Since) to avoid re-downloading an unchanged card.
  • When the server returns no caching headers, MAY apply an implementation-specific default cache duration.

The extended Agent Card and access control

The public card can declare capabilities.extendedAgentCard: true so that authenticated clients can retrieve a more detailed version (for example, additional skills) with GetExtendedAgentCard. The client MUST use a scheme declared in the public card and SHOULD replace its cached public card with the extended one for the duration of the authenticated session.

An Agent Card can contain sensitive information. Implementers can protect it with access control and by requiring authentication and authorization: for example, inside an organization, even open discovery on the .well-known path can be restricted to specific clients with mTLS, and registries and private discovery APIs SHOULD require authentication and return different content for different identities. Never put credentials such as API keys in an Agent Card without authentication protection.

Related pages

Source: A2A official specification · Agent Discovery: The Agent Card