Pydantic AI keeps its own auth hook. Authdog stays the identity provider. The sample attaches an agent access token there and refuses the run when that token is missing or userinfo rejects it.

Sample: [pydantic-ai/python](https://github.com/authdog/agents-samples/tree/main/pydantic-ai/python). Python 3.10+. Package `pydantic-ai==2.59.0`.

Channel auth, machine credentials, tool checks, and instructions for this framework are the other pages under Pydantic AI in [AI](/docs/ai/pydantic-ai/channel-auth).

## The hook

```python
@dataclass(frozen=True)
class Caller:
    token: str

agent = Agent("test", deps_type=Caller)

@agent.tool
async def whoami(ctx: RunContext[Caller]) -> str:
    """Return the Authdog subject for this caller. Do not invent one."""
    return await fetch_subject(ctx.deps.token)
```

`Caller.token` is the access token. The client secret is not a field on `Caller`. `fetch_subject` sends `Authorization: Bearer` to an API whose route depends on `require_auth`. A missing or rejected token does not return a subject. Tests call that helper and the route. They do not call the model.

This is agent identity: `client_credentials`, then this hook. It is not [Agent Sign-In](/docs/agent-sign-in). A browser sign-in does not replace the hook.

## What you should see

`GET /whoami` with no token is `401`. The helper, given an empty token, does not return a subject.

The same call with a bearer userinfo accepts returns `{"subject":"<id>"}`. The tool result is that string.

`pytest` in `pydantic-ai/python` checks both. It does not call a model.

## Configure

| Name | Purpose |
| --- | --- |
| `PK_AUTHDOG` | Public key on the API process. |
| `Caller.token` | Access token on the run. Not the client secret. |

The shared exchange is in [Agent frameworks](/docs/agent-frameworks#mint-the-bearer). There is no refresh token. Repeat it before `expires_in`.

> **Caution**
>
> Do not commit the client secret, and do not put the access token in the prompt. The public key selects the identity host. It does not mint tokens.

## Related

| Read | To learn how to |
| --- | --- |
| [Agent frameworks](/docs/agent-frameworks) | Mint the bearer this hook checks |
| [Google ADK](/docs/agent-frameworks/adk) | The previous hook |
| [Claude Agent SDK](/docs/agent-frameworks/claude-agent) | The next hook |
| [Custom channel auth for Pydantic AI](/docs/ai/pydantic-ai/channel-auth) | The same check, as the auth boundary |
