Agent-to-Agent Authorization: What A2A Actually Guarantees (and What It Quietly Hands Back to You)

AAIF just gave MCP and A2A the same governance home. That's a coordination story, not a security fix. Here's what A2A's spec actually guarantees about agent-to-agent authorization, and the three holes you still have to close yourself.

The Governance Story Everyone Told This Week

On August 17, 2026, Google's Agent-to-Agent protocol joined the Agentic AI Foundation, the Linux Foundation body that already stewards Anthropic's MCP, Block's goose runtime, and OpenAI's AGENTS.md convention. The headline write-ups called it a milestone: two of the most important protocols in the agentic stack, finally under one neutral roof.

Read past the headline and the framing gets more precise. A2A left Google's sole control back in June 2025, when it went to the Linux Foundation with AWS, Cisco, Microsoft, Salesforce, SAP, and ServiceNow already backing it. Forbes' coverage of the move makes the point directly: what changed this month is which foundation hosts the specification work, not who controls it. MCP and A2A keep separate maintainers, separate release schedules, separate spec processes. They just sit under the same governance umbrella now.

That distinction matters more than it sounds like it should. The thing most people actually want from a "merger" of agent protocols, a shared answer to who is allowed to do what when one agent calls another, isn't something a shared foundation home provides. It isn't even something A2A's own spec fully provides on its own. That's the part worth spending real time on.


What A2A's Spec Actually Says About Authorization

Every A2A interaction starts with the object the A2A specification builds everything around: the Agent Card. It's a JSON document, published at a well-known endpoint, that describes an agent's identity, its skills, its service URL, and how a caller is supposed to authenticate to it.

{
  "name": "invoice-agent",
  "description": "Handles invoice queries and updates",
  "url": "https://agents.example.com/invoice",
  "skills": [
    {"id": "invoice.read", "description": "Read invoice records"},
    {"id": "invoice.write", "description": "Create or update invoices"}
  ],
  "securitySchemes": {
    "oauth2": {
      "type": "oauth2",
      "flows": {
        "clientCredentials": {
          "tokenUrl": "https://auth.example.com/oauth/token",
          "scopes": {
            "invoice.read": "Read invoice records",
            "invoice.write": "Modify invoice records"
          }
        }
      }
    }
  },
  "security": [{"oauth2": ["invoice.read"]}]
}

The Agent Card itself is intentionally left unauthenticated as a discovery mechanism. A client fetches it before it holds any credentials at all, reads which auth scheme the remote agent expects, bearer token, API key, mTLS, OpenID Connect, and only then goes and acquires a credential through whatever out-of-band flow that scheme requires.

Once a request lands with valid credentials attached, the spec hands authorization to the receiving agent, and it's explicit that this part is implementation-defined. Servers MAY consider which skill was requested, what action it involves, what data it touches, and what OAuth scopes rode in on the token. The spec also says servers should implement least privilege. It does not tell you how to enforce any of it.

A minimal enforcement pattern looks like this:

from fastapi import FastAPI, Header, HTTPException
import jwt

app = FastAPI()

def verify_scope(token: str, required_scope: str) -> dict:
    claims = jwt.decode(token, options={"verify_signature": True}, algorithms=["RS256"])
    scopes = claims.get("scope", "").split()
    if required_scope not in scopes:
        raise HTTPException(status_code=403, detail=f"missing scope: {required_scope}")
    return claims

@app.post("/a2a/tasks/send")
async def handle_task(payload: dict, authorization: str = Header(...)):
    token = authorization.replace("Bearer ", "")
    # Enforce least privilege at the handler, not just at the gateway
    claims = verify_scope(token, required_scope="invoice.read")
    # claims["sub"] identifies the calling agent, or a human delegated through it
    return {"status": "accepted", "caller": claims["sub"]}

This is the same OAuth-scope pattern that has protected human-facing APIs for over a decade, and A2A leans on it deliberately instead of reinventing it. The tradeoff, laid out well in a primary-source read of A2A's auth model, is that "the protocol has authorization" quietly becomes "your integration layer has authorization, if you built it."


Where This Breaks in Practice

Three gaps show up consistently once you go past a single hop.

Agent Card authenticity

The card tells a caller which auth scheme to use, but nothing in the spec mandates how the card itself gets verified as genuine. There's no built-in barrier to an attacker standing up a look-alike endpoint with a copied Agent Card and harvesting credentials meant for the real agent. Security analysis of A2A points to signed Agent Cards plus mTLS-backed machine identity as the practical fix. That's a convention teams have to add on top, not something the base spec requires.

Multi-hop delegation

A2A's actor model expects chains: a client agent delegates to a remote agent, which itself becomes a client agent delegating to the next one. An orchestrator hands a task to a data agent, which hands a sub-task to a reporting agent. Each hop needs its own answer to whether the narrower request still fits inside the original grant, and a bearer token has no native way to attenuate itself as it passes down the chain. Shrinking a token's authority from "read invoices" to "read invoices for customer 4471 only" means minting a new token, which breaks the audit trail connecting it back to the original grant.

Cross-domain trust

OAuth-based schemes assume both sides trust the same authorization server, or federate through OIDC. Reasonable inside one company. It breaks down the moment your orchestrator needs to call a partner's agent across an organizational boundary, which is precisely the scenario A2A was built to support in the first place.

Researchers are already proposing agent-specific identity layers on top of OAuth, extending JWTs with structured claims for task binding, capability scope, and delegation chains. One such proposal gets a lot right, and it names its own limitation plainly: JWTs are immutable once signed, so a holder can't attenuate authority offline without minting a new token that breaks the cryptographic chain. That's exactly the friction multi-hop, cross-domain agent networks are trying to avoid, not solve twice.


What This Means for What You're Building

None of this is a reason to avoid A2A. It's a reason to stop treating "we support A2A" as a security answer on its own.

If your agents only call other agents inside one trust domain, standard OAuth client-credentials flow plus mTLS at the transport layer covers most of what you need. It's the same pattern most teams already run for service-to-service auth. Enforce skill-scoped checks at the handler level the way the spec expects, rather than assuming a valid token alone is sufficient.

If your agents need to cross organizational boundaries, budget real engineering time for signed Agent Cards and an explicit delegation-chain design before you ship, not after. It's the same lesson from designing guardrails and loop budgets for autonomous agents: the failure modes that matter in production only show up once you're past the demo and into a real multi-agent topology, not before.

And if you're wondering whether AAIF's shared governance changes your risk posture here, it doesn't, not directly. It gives the ecosystem one place to track the spec's evolution instead of two, which is a genuine operational win over the fragmented state described in the full 2026 agentic stack breakdown. It says nothing new about how your specific deployment handles a compromised Agent Card or an over-broad delegated token. That part is still, entirely, on you.


Further Reading

Subscribe to Vivek Wisdom

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe