A2A's auth boundary has two surfaces. The agent card is public and tells a client how to get a token. The JSON-RPC mount is the gate. Publishing the card does not protect SendMessage.
Getting started, including the runnable sample, is A2A.
Declare Authdog on the card
Build an OAuth 2 client-credentials scheme whose token URL is the environment token_endpoint. Attach it as security scheme authdog with scope agent:invoke.
flow = ClientCredentialsOAuthFlow(token_url=token_url)
flow.scopes["agent:invoke"] = "Call this agent"
scheme = SecurityScheme(
oauth2_security_scheme=OAuth2SecurityScheme(
description="Authdog agent identity (client credentials)",
flows=OAuthFlows(client_credentials=flow),
)
)The token URL is public configuration. The client secret never goes on the card. GET /.well-known/agent-card.json stays open so a client can discover the scheme.
Require the bearer on JSON-RPC
Construct Authdog(public_key=...) from PK_AUTHDOG. Wrap /a2a so require_auth runs before the executor.
class _Gate(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
try:
user = await authdog.require_auth(request)
except HTTPException:
return JSONResponse(
{"error": "Unauthorized"},
status_code=401,
headers={"WWW-Authenticate": "Bearer"},
)
request.state.authdog_subject = subject_of(user)
return await call_next(request)subject_of reads user["id"], then user["sub"]. A missing bearer, a userinfo rejection, or a payload with no subject is 401. The executor reads authdog_subject from request state. It does not read the raw Authorization header.
SendMessage also requires A2A-Version: 1.0. A protocol error from a missing version header is separate from the 401.
Leave the client secret on the process that mints the token. The server process holds PK_AUTHDOG and the token URL. See API keys and M2M for A2A.
Related
| Read | To learn how to |
|---|---|
| A2A | Run the sample and see the 401 |
| API keys and M2M for A2A | Put the secret on the client, not the card |
| Authorizing tool calls for A2A | Decide what that subject may do |
| Agent frameworks | Mint the bearer this gate checks |