An AI agent can now describe itself twice, once as an A2A Agent Card that tells other agents how to call it and once as an OAuth client metadata document that tells an authorisation server who is asking for tokens, and attackers exploit the gap when nobody checks that both describe the same agent. The two documents are not alternatives. An Agent Card describes an agent in its server role; a Client ID Metadata Document (CIMD) or a Dynamic Client Registration (RFC 7591) record describes it in its client role. Most production agents play both roles. This guide explains what each document asserts, who stands behind it, what it must and must not be trusted for, and how to bind the two so a spoofed card or an open registration cannot borrow a legitimate agent's identity. It is for identity architects, platform engineers and authorisation server operators. How to sign and verify cards is in the A2A Protocol Security Guide and the CIMD flow is in the OAuth Client ID Metadata Documents (CIMD) Guide; this page covers the join between them.
Key takeaways
- Different roles, different readers. An Agent Card is read by A2A clients deciding how to call a server. Client metadata is read by an authorisation server deciding whom to issue tokens to. One agent usually needs both.
- Neither document is authorisation. A card says which authentication schemes a server accepts; the A2A specification leaves authorisation to the server. Client metadata says who a client claims to be; the authorisation server's trust policy decides what that is worth.
- The trust anchors differ. A card can carry a JWS signature from its provider. A CIMD is trusted through control of its HTTPS URL. DCR metadata is self-asserted unless it arrives in a signed software statement.
- Bind them through origin, keys and a registry. The card's URL, its signing key set, the client_id URL and the authorisation server it names should resolve to the same controlled domain and the same registry record.
- Open DCR and unsigned cards are the weak pair. Together they let anyone publish a convincing description and obtain a client registration that looks like a known agent.
What each document is and its status
A2A Agent Card
The A2A specification requires every A2A server to make an Agent Card available, describing its identity, capabilities, skills and interaction requirements. Clients find cards at https://{server_domain}/.well-known/agent-card.json, through curated registries, or by direct configuration. The card's securitySchemes field tells a client which authentication schemes the server requires (API key, HTTP authentication, OAuth 2.0, OpenID Connect or mutual TLS), and an OAuth 2.0 scheme can carry an oauth2MetadataUrl pointing to the authorisation server's RFC 8414 metadata. Cards may be signed with JWS over an RFC 8785 canonicalised payload. The specification page lists 1.0.0 as the latest released version when checked on 13 November 2026; release candidates for later versions exist, so confirm field names against the version you implement.
OAuth client metadata
An OAuth client describes itself to an authorisation server through registration metadata: client name, redirect URIs, grant types, authentication method and keys. There are three ways to get that metadata to the server. Pre-registration is a manual or administrative step. Dynamic Client Registration (RFC 7591) lets the client POST its metadata to a registration endpoint and receive a client_id. CIMD makes the client_id itself an HTTPS URL that points to a JSON metadata document, which the server fetches. CIMD is an OAuth Working Group Internet-Draft, draft-ietf-oauth-client-id-metadata-document-03 dated 2 November 2026 when checked; drafts change. The MCP authorisation specification (version 2025-11-25) says clients and authorisation servers SHOULD support CIMD and MAY support DCR, which it keeps for backwards compatibility.
Side-by-side comparison
| Property | A2A Agent Card | OAuth client metadata (CIMD or DCR) |
|---|---|---|
| Describes the agent as | A server other agents call | A client requesting tokens |
| Primary reader | A2A clients and registries | The authorisation server, then the user at consent |
| Where it lives | Well-known URI on the agent's domain, a registry, or local configuration | CIMD: the client_id URL. DCR: stored by the authorisation server after registration |
| What it asserts | Name, provider, interfaces and URLs, skills, required security schemes, capabilities | Client name, redirect URIs, grant types, token endpoint authentication method, public keys |
| Who stands behind it | The provider, if the card is signed and the key is trusted; otherwise only the TLS certificate of the host | CIMD: whoever controls the HTTPS URL. DCR: nobody, unless a signed software statement names an issuer the server trusts |
| Integrity mechanism | Optional JWS signatures (alg, kid, optional jku) over a JCS canonical form | CIMD: TLS and exact client_id match, no redirects followed. DCR: optional software statement (signed JWT with iss) |
| Secrets allowed | None should be embedded; credentials are obtained out of band | CIMD prohibits shared secrets and allows only public keys. DCR may issue a client secret |
| Must be trusted for | Where to connect and how to authenticate | Which client the authorisation server is dealing with and where it may send codes |
| Must not be trusted for | Whether the caller is allowed to do anything; the server's real behaviour | Whether the client is safe, who is running it, or what scopes it should get |
Threat model for each document
Agent Card threats
- Spoofed card: a look-alike domain or a poisoned registry entry serves a card with a familiar name and provider. ATLAS lists masquerading as AML.T0074, and ATT&CK as T1036.
- Tampered card: an attacker with write access to the hosting path or a registry changes interface URLs or the
oauth2MetadataUrl, so clients send credentials or users to the attacker's authorisation server (T1557 Adversary-in-the-Middle). - Key substitution: a signed card whose
jkupoints to a key set on a domain the provider does not control. The signature verifies, but against the attacker's key. - Over-disclosure: internal skills or endpoints exposed on the public card. The A2A discovery guidance recommends authenticated extended cards and access control on the card endpoint for sensitive details.
Client metadata threats
- Open DCR impersonation: RFC 7591 says a server SHOULD allow registration requests with no authorisation unless it protects the endpoint, and that metadata not in a signed software statement MUST be treated as self-asserted. A rogue client can copy a known agent's name and logo.
- CIMD localhost impersonation: the MCP specification warns that anyone can present a legitimate client's metadata URL with a localhost redirect URI and receive the code when the user approves; the user sees the real client's name.
- SSRF through the fetch: the authorisation server fetches a URL supplied by an unknown party. The CIMD draft requires refusing URLs that resolve to special-use IP addresses and not following redirects. OWASP lists this class as API7:2023 Server Side Request Forgery.
- Token theft after registration: once registered, a client that obtains codes or refresh tokens can replay them (T1528 Steal Application Access Token). Audience-restricted tokens using RFC 8707 resource indicators limit where they work.
Discovery is not authorisation
Both documents answer "who is this and how do I talk to it", never "may it do this". The A2A specification states that identity is handled at the protocol layer, that servers MUST authenticate every request, and that authorisation logic is implementation specific and may consider skills, actions, data policies and OAuth scopes. Section 13.1 requires authorisation checks on every operation and results scoped to the caller. On the OAuth side, the MCP specification describes trust policies as the authorisation server's choice: allowlists for protected servers, accepting any HTTPS client_id for open servers, reputation checks, and domain age or certificate restrictions. Neither a valid signature on a card nor a well-formed CIMD should raise an agent's privileges. They establish that you are dealing with the agent the owner published; entitlement still comes from the registry, the scopes granted at consent and the server's own policy. The Agent-to-Agent Authentication Guide covers the credential exchange that follows discovery.
Binding an Agent Card to its OAuth client
Neither specification defines a field that links a card to a client registration: the A2A AgentCard has no client_id, and client metadata has no card reference. The binding has to come from how you publish and verify them. The pattern below is NHI Mgmt Group design guidance built on what each specification does define.
| Binding check | What to verify | Why |
|---|---|---|
| Same controlled origin | The card URL, the CIMD client_id URL and the card's jku are on the same registrable domain the provider controls, or on domains listed in the registry record | Stops a valid-looking card on one domain borrowing a client identity on another |
| Provider consistency | The card's provider.url and provider.organization match the registry owner and the client_uri in the client metadata | Makes name and logo copying visible |
| Authorisation server identity | The oauth2MetadataUrl in the card resolves to RFC 8414 metadata whose issuer exactly matches, and that issuer is on your allowlist | Prevents a tampered card redirecting clients to an attacker's authorisation server |
| Resource identity | Protected resource metadata (RFC 9728) for the card's interface URL names the same authorisation server, and its resource value is identical to the URL used | Ties the endpoint in the card to the token audience |
| Key separation with common publication | The card signing key and the client's private_key_jwt key are different keys, both published under the provider's domain and both recorded by key ID | Lets one key be revoked without breaking the other, while still proving common control |
| Registry join | One registry record holds the card URL and content hash, signing key IDs, client_id, redirect URI hosts and owner | Gives the authorisation server and A2A clients the same answer to "is this the agent we approved" |
Your AI agent registry is the natural place for the join. When the authorisation server sees a URL-formatted client_id, its trust policy looks up the registry by client_id host; when an A2A client fetches a card, it checks the registry by card URL and content hash. Both should land on the same record or neither proceeds.
Choosing a registration method for the client side
| Situation | Recommended client registration | Card handling |
|---|---|---|
| Internal agents calling internal servers | Pre-registration, or CIMD on an allowlisted internal domain | Cards from the internal registry only; signatures required |
| Partner agents with an agreement | CIMD with a domain allowlist, or DCR with an initial access token issued to the partner | Pin the partner's card signing keys in a trusted key store |
| Public agents connecting to an open server | CIMD with reputation checks, hostname shown at consent, warnings for localhost-only redirects | Accept unsigned cards only for low-risk, read-only skills |
| Legacy clients that only speak DCR | Protected DCR (initial access token) or DCR with signed software statements from issuers you trust; rate limits | Treat the registration as unverified until bound to a registry record |
Small organisations with a handful of agents can skip CIMD and DCR entirely: pre-register each client, sign each card with one key and keep a short allowlist. Large or multi-tenant platforms need CIMD or protected DCR for scale, which makes the registry join and trust policy essential. The OAuth Dynamic Client Registration Security Guide covers DCR hardening.
Worked scenario: a procurement agent
A company runs a procurement agent that other business units' agents call through A2A, and that itself calls a supplier's MCP server. It publishes a signed Agent Card at https://procure.example.com/.well-known/agent-card.json, with jku on the same host and an OAuth 2.0 scheme whose oauth2MetadataUrl points to the corporate authorisation server. For its client role it uses a CIMD at https://procure.example.com/oauth/client.json, with private_key_jwt and a jwks_uri on the same host. The registry record joins card hash, both key IDs, the client_id and the owner. During a review an analyst finds a second card for "Procurement Agent" on a look-alike domain in a team's local configuration, with valid TLS and a valid signature from a key on that domain. The registry check fails because the card URL and key host do not match the record, so clients refuse it. At the supplier, an attempted registration through the open DCR endpoint using the same name and logo is held because no software statement accompanies it and the client_uri host does not match the CIMD the supplier has allowlisted. Neither attempt needed a broken signature; both failed on binding.
How to implement: phased approach
- Inventory both roles: list every agent's card URLs and every OAuth client it holds, by authorisation server. Mark agents that act in both roles.
- Create the registry join: add card URL, content hash, signing key IDs, client_id and redirect URI hosts to each registry record. See the Agent Naming and Discovery Guide for naming.
- Sign cards in report mode: publish signed cards and have clients verify and log failures without blocking for two to four weeks.
- Close open registration: require an initial access token or software statement on DCR endpoints, or move clients to CIMD with a domain allowlist.
- Enforce binding: clients reject cards that fail signature or registry checks; the authorisation server rejects client_ids whose host is not bound to a record.
- Plan rollback: keep a per-agent override in the registry so a failing binding can be relaxed to report mode while the owner fixes it, with expiry and approval.
- Rotate and re-verify: publish new keys alongside old ones (the A2A specification allows multiple signatures for rotation), update the registry, then retire old keys. See the JSON Web Key Sets (JWKS) and Signing Key Rotation Guide.
Detection and measurement
- Signed card coverage: percentage of agent cards in the registry that are signed and verify against a registered key.
- Binding failures: card or client_id checks that fail registry matching, per week, with each investigated.
- Unbound registrations: client registrations at your authorisation servers with no matching registry record; target zero for protected servers.
- Card drift: content hash changes not preceded by a registry update.
- CIMD fetch anomalies: fetches refused for special-use addresses, redirects or oversized responses.
- Localhost-only consents: consents granted to clients whose only redirect URIs are loopback, reviewed for unexpected client names.
Common failure patterns
- Treating a valid signature as trust: verifying a card against whatever key its
jkunames, rather than a key bound to the provider. - Open DCR left on: a registration endpoint inherited from an early MCP deployment accepts anyone, and its registrations are never reviewed.
- Card and client on unrelated domains: a hosting platform domain for the card and a corporate domain for the client, with nothing recording that they belong together.
- Using the card for authorisation: granting an agent rights because its card lists a skill, rather than from the registry and granted scopes.
- Secrets in cards: static keys or tokens placed in card fields, against the A2A guidance to obtain credentials out of band.
- Caching without re-validation: clients and authorisation servers keep stale cards or metadata after a key or redirect URI change.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | IA-9 Service Identification and Authentication | Authenticating agents as services before use |
| NIST SP 800-53 Rev. 5 | SI-7 Software, Firmware, and Information Integrity; SC-8 Transmission Confidentiality and Integrity | Card signatures and TLS on metadata fetches |
| NIST SP 800-53 Rev. 5 | CM-8 System Component Inventory; SA-9 External System Services | Registry of agents and partner agents |
| NIST CSF 2.0 | ID.AM-02, PR.AA-01, PR.AA-03, PR.DS-02 | Inventory, identity management, authentication, data in transit |
| MITRE ATT&CK v20 | T1036 Masquerading; T1557 Adversary-in-the-Middle; T1528 Steal Application Access Token | Spoofed cards, redirected flows, stolen tokens |
| MITRE ATLAS | AML.T0074 Masquerading | Look-alike agent descriptions |
| OWASP API Security Top 10 2023 | API7:2023 Server Side Request Forgery | Authorisation server fetching client-supplied URLs |
Practitioner checklist
- Record for every agent both its card URLs and its OAuth client_ids.
- Sign Agent Cards and verify against keys bound to the provider, not just the
jku. - Check the card's
oauth2MetadataUrlissuer against an allowlist. - Keep card, key set and client_id on domains recorded in the registry.
- Require an initial access token or software statement for DCR.
- Show the client_id hostname at consent and warn on localhost-only redirects.
- Block CIMD fetches to special-use addresses and never follow redirects.
- Use separate keys for card signing and client authentication.
- Authorise from the registry and granted scopes, never from card content.
- Alert on unbound registrations and card hash drift.
Standards and references
- A2A Project: Agent2Agent Protocol Specification
- IETF: OAuth Client ID Metadata Document (Internet-Draft)
- IETF: RFC 7591 OAuth 2.0 Dynamic Client Registration Protocol
- IETF: RFC 8414 OAuth 2.0 Authorization Server Metadata
- IETF: RFC 9728 OAuth 2.0 Protected Resource Metadata
- Model Context Protocol: Authorization specification
- A2A Project: Agent Discovery
Related NHI Mgmt Group resources: Agent Protocols Compared · MCP Authorisation Specification Guide · OAuth Client Registration Checklist · Know Your Agent (KYA) Guide · Agent Authentication vs Agent Attestation