Skip to content
Agentic Control Plane

Per-User Auth for AutoGen Agents

David Crowe · 3 min read
autogen authentication identity governance

If you’ve built anything real on AutoGen, you’ve hit this: the framework gives you agents, group chats, and tool use — and almost nothing on who the agent is acting for. AutoGen’s own guidance is explicit that authentication and authorization are “left to the application code.” That’s a reasonable boundary for a framework to draw, but it leaves a real gap in production: your AutoGen agents call backend tools with one shared service credential, and your backend can’t tell whether a tool call originated from the CFO’s session or an intern’s.

This post is the application-code answer AutoGen points you at — done once, generically, instead of hand-rolled per tool.

The three-party gap, AutoGen edition

A normal app has two parties: a user and your backend, with the user’s identity on every request. An agent inserts a third party in the middle. The user talks to your AutoGen agent; the agent calls your tools. By default the tool call carries the agent’s identity (a shared API key), not the user’s. Your backend sees service-account-prod and has no idea which human is behind the action.

That’s fine until the first time it isn’t — a compliance question (“which user accessed that record through the assistant?”), a per-user rate limit, a tool only some users should reach, or an audit that needs to name a person, not a key. None of those are answerable when every AutoGen tool call looks identical.

What “per-user auth” actually requires

Authenticating the session isn’t enough — you verify a token at the edge and then lose the identity the moment the agent starts calling tools. Per-user auth for agents means the user’s verified identity is present and enforced at each tool call:

  • Verify the end user’s token (JWT against your IdP’s JWKS) — Auth0, Okta, Entra, Cognito, any OIDC provider.
  • Bind that identity to the agent’s run, so it rides along to every tool the agent invokes.
  • Scope each tool call to a strict subset of what that user is allowed — the agent can never exceed the human behind it.
  • Audit every call with the user attached, so “who did what through the agent” is a query.

Wiring it into AutoGen

The pattern is: verify the user once per request, set the identity into the run context, and let a governance layer enforce policy on each tool call. Concretely, you wrap your AutoGen tools so that before any of them executes, the call is checked against your policy with the bound user identity — allow, deny, or redact — and logged.

# Verify the end user's JWT at your entry point, then bind it for the run.
user = verify_jwt(request.headers["authorization"])   # sub, scopes, org
set_context(user_id=user.sub, scopes=user.scopes)

# Wrap the tools your agents use. Each call is now governed + attributed.
@governed
def get_customer(customer_id: str) -> dict:
    ...

# Hand the governed tools to your AutoGen agents as usual.

Now every get_customer call an AutoGen agent makes — inside a group chat, a nested team, a hand-off — carries the originating user, is checked against policy before it runs, and lands in an identity-attributed audit log. The agent’s tools inherit the user’s permissions instead of a shared key’s.

Keep the tool surface narrow

One caveat that makes this hold: per-user auth is only as meaningful as your tools are typed. If an AutoGen agent has a bash or generic-exec tool, the identity binds but the policy can’t bound what the call does — bash collapses everything into one opaque action. Give your agents narrow, typed tools (the specific operations they need), and per-user scope becomes enforceable. That’s least-privilege tool design, and it’s the precondition for any of this working.

Where to start

  1. Verify the end user’s token at your AutoGen entry point and bind sub + scopes into the run context.
  2. Wrap your tools so each call is policy-checked against the bound identity before it executes — not just at the session edge.
  3. Scope and audit per user — the agent’s reach is a subset of the human’s, and every tool call names that human.

AutoGen draws the line at “auth is your job.” This is how you do that job once, across every agent and tool, instead of per handler. See the AutoGen integration for the install, or how to govern AI agent tool calls for the full enforcement picture.

Get the next post
Agentic governance, AgentGovBench updates, the occasional incident post-mortem. One email per post. No marketing fluff.
Share: Twitter LinkedIn
Related posts

← back to blog