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](/docs/agent-frameworks/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`.

```python
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.

```python
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](/docs/ai/a2a/api-keys-and-m2m).

## Related

| Read | To learn how to |
| --- | --- |
| [A2A](/docs/agent-frameworks/a2a) | Run the sample and see the `401` |
| [API keys and M2M for A2A](/docs/ai/a2a/api-keys-and-m2m) | Put the secret on the client, not the card |
| [Authorizing tool calls for A2A](/docs/ai/a2a/authorize-tool-calls) | Decide what that subject may do |
| [Agent frameworks](/docs/agent-frameworks) | Mint the bearer this gate checks |
