The model can choose to call whoami. It cannot choose the subject. The API returns 401 when the bearer is missing or rejected, and {"subject":"<id>"} when userinfo accepts it. The tool returns that result to the model.
What the sample checks
The route depends on require_auth. The tool copies Caller.token into the Authorization header and returns the JSON subject, or raises when the response is not successful. pytest covers the route and fetch_subject. It does not call Runner.
That is the whole permission check in the sample. A subject in the tool result means userinfo accepted this token. If you add a tool that refunds an order or deletes a user, that tool's API has to authorize the action. Returning the error string to the model is how the agent learns the call was refused. Swallowing the 401 and inventing a success is the failure mode the docstring is written to prevent.
| Check | Where |
|---|---|
| Bearer present and accepted | GET /whoami, or whatever route the tool calls |
| Allowed tools for an agent | Trust-store row, if that API enforces it. This sample does not. |
| The action | Authorization on the route, after require_auth |
Revoke in Agents makes the next token exchange fail when the subject is the OIDC client id. The access token already sitting in Caller lasts until expires_in unless the API rejects it.
When Caller.token is an RFC 8693 token, authorize the user in sub. The tool does not get to promote the agent to that user.
Related
| Read | To learn how to |
|---|---|
| Custom channel auth for the OpenAI Agents SDK | Put require_auth on the route |
| Enriching instructions for the OpenAI Agents SDK | Tell the model not to invent a subject |
| Authorization | Add the check the next tool needs |
| LangGraph | Apply the same idea inside a graph node |