Authdog

Custom channel auth for A2A

Last updated Oct 21, 2026
View as Markdown

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.

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

Learn more