Skip to content

The A2A Handshake: What Agent2Agent Authentication Actually Proves

8 min read Fullmakt Team

  • a2a
  • mcp
  • authentication
  • agents
  • governance
  • traceability

Agents are starting to talk to other agents directly, not just to tools. The Agent2Agent protocol (A2A) is the emerging standard for that: a shared way for one agent to discover another’s capabilities, hand it a task, and get a result back — without either side needing bespoke integration code. That’s useful. It also introduces a handshake most teams haven’t thought hard about yet: what does it actually mean for Agent A to prove to Agent B’s host that it’s allowed to ask for something, and who’s watching what happens after it does?

This is the same authentication-versus-authorization gap we’ve written about for MCP and OAuth 2.1 and for login handshakes generally, but A2A raises the stakes: now the party on the other end of the handshake is itself an agent, acting unattended, that will turn around and make its own decisions about what to do with whatever access it just received.

What the A2A handshake actually is

Strip away the JSON-RPC framing and A2A’s authentication story is a familiar shape: discovery, then a standard OAuth grant, then scoped calls.

  1. Discovery. A calling agent fetches a well-known Agent Card — a public JSON document describing what the other side offers: its skills, their input schemas, and its security scheme. No credential is needed to read it.
  2. Token acquisition. The card advertises how to authenticate — commonly an OAuth 2.0 client-credentials flow against a token endpoint, returning a bearer token scoped to a specific grant (e.g., a management scope tied to one workspace).
  3. The call. The calling agent sends a JSON-RPC message/send request carrying a structured payload — in practice, “run this skill with this input” — and gets back a terminal Task object: completed, with a result, or failed, with a reason.

That’s the whole handshake. It answers one question well: is the bearer of this token a legitimate agent, provisioned for this workspace, entitled to speak to this surface at all. It does not answer the question that actually determines whether anything goes wrong: should this specific skill run, with these specific arguments, right now.

The gap: a valid handshake is not a safe action

This is where “AI agentic gone wrong” stories actually start. The postmortem rarely says the agent was unauthenticated — it usually had a perfectly valid token, correctly scoped to the workspace it was calling into. The failure was downstream of the handshake: the token was broad enough to reach an operation nobody meant to expose to an agent, or a chain of agent-to-agent calls extended a task well past what the human who kicked it off actually authorized.

A2A makes this easier to get wrong than a single-agent-to-API call, for two reasons specific to the protocol:

  • The skill catalog is data, not code review. The Agent Card is generated and machine-readable; a skill added to the catalog is immediately callable by any agent holding a valid token for that scope. There’s no human eyeballing each new capability before an agent can reach it — the catalog is the permission surface.
  • A handshake, once passed, doesn’t re-check itself per call. A token minted for a legitimate task doesn’t know the task changed. If a prompt-injected instruction three hops downstream redirects the calling agent toward a different skill, the token is still valid — the protocol has no built-in notion of “this call doesn’t match what I was actually asked to do.”

Put differently: the handshake proves identity and coarse scope. It says nothing about whether this call, from this agent, right now, is one a human would sign off on if they were watching. That’s a policy decision, and policy decisions need to be made per call, not once at login.

Two structural fixes that don’t rely on trusting the agent

The honest answer isn’t “make agents behave better.” It’s removing entire classes of decisions from the agent’s reach and putting a check in front of every call that a token alone can’t bypass. Two patterns do most of the work:

A hard-coded deny list, independent of what’s registered. However carefully a skill catalog is curated, mistakes happen — a capability gets added, renamed, or exposed to a scope it shouldn’t be in. The fix is a gate that denies certain operations by pattern before it ever looks at the catalog: credential setup and rotation, principal-to-identity bindings, and approval decisions are denied outright, no matter what’s registered or what scope the token carries. An agent can reference a stored credential to use it. It can never create, rotate, or delete one, and it can never decide its own pending approval. Those stay human-only by construction, not by convention — which matters, because conventions are exactly what a compromised or confused agent won’t respect.

An audit entry for every attempt, allowed or denied. Every call across the handshake — who called, which skill, what workspace, whether it was allowed or denied and why, how long it took — gets written to the same record used for every other agent surface in the system. A denied call isn’t just silently rejected; it’s evidence. If an agent keeps trying an operation it shouldn’t reach, that pattern is visible in the log before it becomes an incident, not after.

Neither of these depends on the calling agent doing anything correctly. That matters, because in agent-to-agent chains, you’re not just trusting the agent you provisioned — you’re trusting whatever it decided to ask a second agent to do on its behalf.

Execution and management are different handshakes, on purpose

One more structural point worth making explicit: the token that lets an agent manage a workspace over A2A — create collections, wire up requests, adjust policy — should not be the same token that lets it execute those requests against real upstream APIs. Keeping the two on separate, narrowly scoped grants (a management handshake for orchestration, a distinct execution-scoped handshake for calling collection-pinned tools over MCP) means a token that leaks or gets misused in one context can’t be replayed in the other. An agent that talks its way into re-provisioning a collection still can’t use that same token to pull data out of it.

This is the same instinct behind not letting one API key do everything for a person — except here it has to be enforced structurally, because there’s no human in the loop to notice the token being used somewhere it shouldn’t be.

The business case: the handshake is table stakes, the broker is the product

This is exactly the layer Fullmakt operates at. A2A and MCP are protocols for discovering and calling capabilities — they’re necessary, and Fullmakt implements both. But standing up the handshake and stopping there leaves the harder half of governance undone: deciding, per call, whether a specific agent should be allowed to do a specific thing right now, guaranteeing that certain operations (credential setup, identity binding, approvals) never become agent-reachable no matter how the catalog evolves, and keeping a tamper-evident record of every attempt — granted or refused — across every agent in the chain.

That’s the difference between “our agents authenticate” and “we can prove what every agent did, to whom, and why it was allowed to.” The first is a protocol implementation. The second is what actually holds up under an audit, an incident review, or an ISO/IEC 42001 conversation. A credential broker sitting behind the A2A and MCP surfaces is what turns a passed handshake into an accountable action — one that’s traceable across every hop it triggers, not just at the front door.

FAQ

What is the A2A (Agent2Agent) protocol? A2A is an open protocol that lets one AI agent discover another agent’s capabilities and delegate tasks to it, using a published Agent Card for discovery and JSON-RPC over HTTP to send tasks and retrieve results.

How does authentication work in A2A? The Agent Card advertises a security scheme — typically an OAuth 2.0 client-credentials flow — that the calling agent uses to obtain a bearer token scoped to a specific grant, such as management access to one workspace. The token is then presented on every subsequent call.

Does a valid A2A token mean the call is safe? No. A valid token proves the caller is a legitimate, correctly scoped agent. It doesn’t evaluate whether a specific call, with specific arguments, should happen right now — that’s a separate policy decision that has to be made on every call, not assumed from a successful login.

Why can’t the skill catalog alone control what agents can do? Because a catalog is data an agent reads, not a human reviewing each request in real time. Sensitive operations — credential setup, identity bindings, approval decisions — need to be denied by a hard rule independent of the catalog, so a registration mistake can’t silently expose them.

How does A2A relate to MCP? They’re complementary. A2A is commonly used for agent-to-agent management and orchestration; MCP is commonly used for the actual execution — an agent calling a specific tool against a specific collection. Keeping the tokens for each on separate scopes limits what a leaked or misused credential can reach.

An agent that passes the handshake isn’t the risk. An agent that passes the handshake and is then trusted to police its own next move is. The protocol gets you in the door correctly authenticated — what happens on every call after that is the part still worth building, and auditing, on purpose.