Card 33 of 40· Secure

Authentication flows: who does the call run as?

Two of the four preserve entitlement and two dissolve it. When an API key is genuinely correct, and when it is a bypass that works perfectly in testing.

Authentication flows: who does the call run as?
Open the card in a new tab to read it at full size.

This is the highest-leverage decision in the security domain, and it comes down to
one question asked of every call an agent makes: whose identity does this run
under?

The syllabus names four mechanisms. Two preserve the user's entitlement and two
dissolve it, and knowing which is which is most of the topic.

The four

On-behalf-of. The agent exchanges the user's token for a token to call a
downstream service as that user. The user's entitlement travels with the call.
This is the default answer.

User impersonation. The agent asserts that it is the user. Entitlement is
preserved, but the downstream system cannot tell the difference between the person
and the agent acting for them.

API keys. The call runs as the service. Whatever the key can reach, every
user of that agent can reach. Entitlement is dissolved.

OAuth 2.0. Not a fourth alternative so much as the framework the others sit
inside — scopes, consent, token lifetime and refresh.

In plain terms: on-behalf-of is the agent showing the user's pass at the door. An
API key is the agent showing its own pass, which usually opens more doors, for
everybody who asks it to.

Why on-behalf-of is the default

For agents this matters more than in ordinary software, because an agent's whole
value is reaching across many systems on someone's behalf — which is also exactly
how it becomes a route around entitlement if the identity does not travel.

Three properties are worth naming:

The downstream system enforces its own access control, unchanged. You are not
reimplementing permissions inside the agent, which is a thing nobody does well.

Retrieval becomes permission-trimmed for free. The knowledge question and the
identity question turn out to be the same question.

The audit trail names a person, not a service. Which is what an investigation
actually needs.

When an API key is genuinely correct

API keys are not always wrong. They are wrong by default and correct narrowly.

Legitimate: calling a service that has no concept of your users at all — a public
dataset, a translation service, a weather API. There is no user entitlement to
preserve, so there is nothing to dissolve.

Illegitimate, and extremely common: reaching an internal system that does have
per-user permissions, using one service credential, "to keep things simple during
the pilot".

The reason that survives so long is worth understanding. It works perfectly in
testing
— because the people testing have broad access anyway, so every answer
looks right. It surfaces months later when somebody receives an answer they should
never have been able to get, and by then it is load-bearing.

The practical defence is a ten-minute table: for each tool and each knowledge
source, write down whose identity the call runs under and why. Any row that says
"service identity" against a system with per-user permissions needs a justification
or a fix. It is also exactly the artefact a security review will ask you for.

Delegation versus impersonation

The syllabus lists both, so the distinction is fair game.

Delegation — on-behalf-of — means the agent holds a token scoped to acting for
this user, obtained through a proper exchange. The downstream service can see it is
a delegated call.

Impersonation means the agent asserts it is the user. Blunter, and harder to
audit, because downstream cannot distinguish the two.

Prefer delegation. The ability to tell "the user did this" from "an agent did this
for the user" is worth a great deal when something goes wrong, and impersonation
destroys precisely that.

Better than any of them: managed identity

Where the call is Azure-to-Azure, the best answer is a credential that does not
exist. Managed identity is issued and rotated by Azure, never seen by your code,
and there is nothing to leak or rotate.

One warning that Microsoft states in its own documentation and that is easy to
carry from a tutorial into production:

"DefaultAzureCredential is convenient for development but requires careful
consideration in production. In production, consider using a specific credential
(e.g. ManagedIdentityCredential) to avoid latency issues, unintended
credential probing, and potential security risks from fallback mechanisms
."

Three named harms. DefaultAzureCredential tries a chain of credential sources —
convenient locally, and in production it means you are not certain which identity
you are actually running as.

Across an agent boundary

When agent A calls agent B, ask three things. Does the user's identity travel — or
has A just laundered entitlement? Does B trust A's assertion about who the user is,
and should it, given A is driven by a model reading untrusted content? And is there
a per-agent identity in the audit trail, so you know both which user and which
agent
?

The trap

"Users should only be able to see what they already have access to" is answered by
on-behalf-of, not by filtering results after retrieval.

Filter afterwards and the data was already in the prompt. A prompt is a place data
leaks from — into traces, into evaluations, into memory, into a summary. The
filtering answer looks careful and arrives one step too late.