When your agent calls a tool, it needs a token your API already knows how to check. Authdog issues that token. LangGraph, the OpenAI Agents SDK, the Claude Agent SDK, and A2A all send the same bearer, and you verify it on your server.

The Agents module is sales-gated. Until that access is approved, create a machine-to-machine application and use `client_credentials`. Keep a development token off your production API.

## What the token says

| Caller | Grant | Claims |
| --- | --- | --- |
| Person | Session JWT | `sub` is the user |
| Workload | `client_credentials` | `sub` is the agent client |
| Agent acting for a person | RFC 8693 token exchange | `sub` is the user, `act` names the agent |

Reject a bad or missing token with `401`. Reject a valid token that lacks the scope or tool with `403`. Check issuer, audience, and expiry on every call.

## LangGraph

Give the worker the client id and secret. Exchange them before the graph runs, and attach the access token on each tool request.

```bash
curl -X POST "$TOKEN_ENDPOINT" \
  -u "$AUTHDOG_CLIENT_ID:$AUTHDOG_CLIENT_SECRET" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials"
```

Pass `Authorization: Bearer <access_token>` from the tool node. Refresh when `expires_in` is close. Do not put the client secret in the prompt.

## OpenAI Agents SDK

Register one confidential client per agent. In the tool's `execute`, read the bearer your channel already verified and call your API with it. A tool that needs a person's account uses token exchange so the user stays `sub` and the agent is in `act`.

## Claude Agent SDK

Same exchange. Put the access token on the MCP client or HTTP tool, not in the system prompt. If a tool is marked as requiring approval, a `403` with reason `approval_pending` means wait. Do not retry until an operator approves it in Agents → Approvals.

## A2A

Put this on the Agent Card. The client fetches the token out of band and sends it on the HTTP request, not inside the JSON-RPC body.

```json
{
  "securitySchemes": {
    "authdog": {
      "openIdConnectSecurityScheme": {
        "openIdConnectUrl": "https://<issuer>/.well-known/openid-configuration"
      }
    }
  },
  "securityRequirements": [{ "authdog": ["mcp:invoke"] }]
}
```

## Related

| Read | To learn how to |
| --- | --- |
| [Machine identity](/docs/machine-identity) | Choose M2M, Agents, a service account, or a PAT |
| [MCP authentication](/docs/mcp-authentication) | Protect an MCP server with the same issuer |
| [Agent delegation](/guides/agent-delegation) | Keep the user as `sub` when an agent acts for them |
