Authdog

Custom channel auth for OpenAI Agents SDK

Last updated Oct 21, 2026
View as Markdown

The OpenAI Agents SDK tool is the caller. It reads an access token from run context and sends Authorization: Bearer to your API. require_auth on that API is the auth boundary. The tool does not decide who the caller is.

Getting started, including the runnable sample, is OpenAI Agents SDK.

Hold the token in context

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

@function_tool
async def whoami(ctx: RunContextWrapper[Caller]) -> str:
    """Return the Authdog subject for this caller. Do not invent one."""
    return await fetch_subject(ctx.context.token, client, url)

whoami sits inside build_agent. client and url come from that function. The full sample is on OpenAI Agents SDK.

Run it with context=Caller(token=...) passed to Runner.run. fetch_subject sets the header only when token is non-empty. An empty token still hits the API, and the API returns 401.

The route is the gate

authdog = Authdog(public_key=public_key)

@app.get("/whoami")
async def whoami(user=Depends(authdog.require_auth)):
    return {"subject": subject_of(user)}

Authdog comes from authdog.fastapi. A missing or rejected token is 401 from this route, including when the tool sends an empty header. The model sees the tool result, which is the subject string the API returned, or the error from a rejected call.

The API process holds PK_AUTHDOG. The agent process holds AUTHDOG_ACCESS_TOKEN. The client secret stays in the process that minted the token. See API keys and M2M for the OpenAI Agents SDK.

Read To learn how to
OpenAI Agents SDK Run the tool and the route
API keys and M2M for the OpenAI Agents SDK Fill Caller.token
Authorizing tool calls for the OpenAI Agents SDK Let the API refuse, and let the model repeat that
LangGraph Protect the workflow this tool calls

Learn more