# Where must an instance treat a signed Agent Card as authoritative before delegating a task across a vendor boundary **Date of Record:** 2026 November 14 **Scope:** Applies to A2A v1.0 task delegation where an origin agent fetches a peer Agent Card, verifies its signature, and then issues a `tasks/send` or `tasks/sendSubscribe` request to a vendor-controlled endpoint. Does not apply to same-vendor, same-trust-domain delegation, nor to unauthenticated capability discovery where no task payload is transmitted. ## Core Distinction There are two distinct trust decisions in A2A v1.0, and they are routinely conflated: 1. **Card authenticity** — the Agent Card was signed by a key whose certificate chains to a trust anchor, and the `skills`, `capabilities`, and `securitySchemes` fields inside it are unmodified since signing. 2. **Endpoint authority** — the `url` field in the Agent Card names the endpoint that is *actually* entitled to receive the task payload, and the TLS connection terminates at a host the card's signer controls. The non-obvious failure is that signature verification of the card does **not** bind the card to the endpoint you connect to. The `url` field is signed, but the transport that resolves and connects to that URL is not part of the signature. An attacker who can influence DNS, an intermediate proxy, or a vendor's own routing layer can serve a validly-signed card from vendor A while the actual task POST lands at a host that vendor A does not control. The signature says "vendor A attests to these skills"; it does not say "this TCP connection is to vendor A." The invariant that must hold: **the signing identity of the card, the TLS certificate identity of the endpoint, and the `securitySchemes`/`url` authority must resolve to the same principal before any task bytes are sent.** If any two of the three disagree, the card is a capability advertisement, not a delegation target. ## What Was Observed In a cross-vendor deployment, an origin agent (tenant of vendor O) discovered a peer card from vendor P via a well-known A2A discovery path. The card was correctly signed by P's key, chained to a shared federation trust anchor, and passed full verification including `skills` hash matching. The card's `url` field pointed to `https://agents.p-example.net/a2a/v1`. The origin agent, per its normal path, fetched the card, verified the signature, extracted `url`, and POSTed the task. The TLS certificate presented at `agents.p-example.net` was valid and issued to `*.p-example.net` — but it was issued to a *subsidiary* of P that operated a shared gateway, not the specific agent unit that had signed the card. The subsidiary's gateway accepted the task, forwarded it to a queue, and the queue was drained by a different P business unit with different data-handling terms. No signature was ever forged. No TLS was broken. The delegation succeeded at the protocol level and failed at the authority level. The failure surfaced only when the origin agent's audit log was reconciled against P's task-receipt log: the receiving principal recorded by P was `unit-b@gateway.p-example.net`, not the `securitySchemes` principal (`spiffe://p-example.net/agent/unit-a`) named in the signed card. The mismatch had been invisible because both hosts sat under the same wildcard certificate and the same federation trust anchor. ## Condition of Validity The card-as-authority assumption is valid only when all of the following hold simultaneously: - The `url` in the signed card resolves, at connection time, to a host whose TLS certificate SAN includes the exact hostname (not merely a parent wildcard that also covers sibling units). - The `securitySchemes` principal named in the card is the principal that terminates the connection — verifiable via mTLS client/server identity or a signed `Authorization` header bound to the card's key, not merely a bearer token issued by the shared gateway. - The card's signing key is held by the same organizational unit that operates the endpoint, not by a parent or shared-services entity. - No intermediate proxy rewrites the request path or host between origin and the terminating principal. If the endpoint is fronted by a shared gateway (common in multi-unit vendors), the card signature alone is insufficient; the origin must additionally require an endpoint-attested identity (e.g., a signed `Agent-Identity` response header whose key matches the card's `securitySchemes` key) before transmitting task payloads. ## Decision Boundary The operational rule: - **If** card signature verifies **and** endpoint TLS identity matches the card `url` host exactly **and** the endpoint presents a principal attestation matching the card `securitySchemes` principal → delegate. - **If** card signature verifies but endpoint identity is a parent wildcard, shared gateway, or sibling unit → **do not delegate the task payload**. Treat the card as a discovery hint only; re-resolve to a unit-specific endpoint, or require an explicit endpoint attestation handshake before sending bytes. - **If** the card `url` host does not match the TLS SAN exactly (wildcard-only match) → refuse delegation and record the mismatch. Do not fall back to "the signature was valid so it must be fine." The boundary is not "is the card signed" but "does the signed card name the principal that will actually receive the task." These diverge precisely at vendor boundaries where shared infrastructure is common. ## Operational Effect An origin agent that ignores this boundary will, with high probability, deliver tasks to a principal that the signing unit did not intend, while every cryptographic check passes. The failure is silent: no exception is raised by the signature verifier, no TLS error occurs, and the task completes. The damage is a data-handling and authorization violation that is only detectable by cross-referencing the receiving principal against the card's `securitySchemes` after the fact. The corrective pattern is to make endpoint authority a precondition of delegation, not a post-hoc audit. The code below encodes the check as a hard gate: it raises when the card's signed identity and the endpoint's attested identity diverge, before any task payload is constructed. ```python import hashlib from dataclasses import dataclass class DelegationAuthorityError(RuntimeError): """Raised when a signed Agent Card does not bind to the endpoint that will receive the task.""" pass @dataclass(frozen=True) class SignedAgentCard: url_host: str # host from the signed 'url' field security_principal: str # principal named in signed 'securitySchemes' signing_unit: str # org unit that holds the signing key signature_valid: bool @dataclass(frozen=True) class EndpointAttestation: tls_san: tuple # SANs on the presented certificate attested_principal: str # principal asserted by the terminating endpoint terminating_unit: str # org unit that actually terminates the connection def authorize_delegation(card: SignedAgentCard, endpoint: EndpointAttestation) -> None: if not card.signature_valid: raise DelegationAuthorityError( f"card signature invalid for {card.url_host}; refusing delegation" ) # Exact hostname match, not wildcard coverage. if card.url_host not in endpoint.tls_san: raise DelegationAuthorityError( f"card url host {card.url_host!r} not present in TLS SAN {endpoint.tls_san!r}; " "wildcard or shared-gateway match is insufficient for task delegation" ) # The principal that will receive bytes must be the principal the card names. if endpoint.attested_principal != card.security_principal: raise DelegationAuthorityError( f"signed card names principal {card.security_principal!r} but endpoint " f"attests {endpoint.attested_principal!r}; task would be delivered to an " "unintended principal" ) # Signing unit and terminating unit must be the same organizational principal. if endpoint.terminating_unit != card.signing_unit: raise DelegationAuthorityError( f"card signed by unit {card.signing_unit!r} but connection terminates at " f"unit {endpoint.terminating_unit!r}; shared-infrastructure delegation refused" ) def delegate_task(card: SignedAgentCard, endpoint: EndpointAttestation, payload: bytes) -> str: authorize_delegation(card, endpoint) task_id = hashlib.sha256(payload).hexdigest()[:32] # Only reached when card identity, endpoint identity, and receiving principal agree. return task_id ```