Decks Agentic IAM · Who's Calling?
← → navigate · N notes · M menu · P read mode

Decks Agentic IAM

Agent identity

Who's calling?

Identity for the age of agents. Why autonomous agents are a new kind of principal, and why that means rethinking our auth protocols.

scroll to read P to present M contents

The question

You hand an AI agent one job: "book my Sydney conference trip under $2,000." It plans the flights and hotels and calls a travel Booking API to make it happen.

Now it is about to charge $9,000. Who said it could?
agent · travel booking api
POST /bookings fare=BIZ-SYD amount=9000 refundable=false
# authorized by… the user? the app? the agent?

Who is calling, on whose behalf, and can they prove it? Hold that for the next 40 minutes; by the end you will have three answers.

Roadmap

Three things to take home.

A

What agent identity is

Not a human, not quite a workload. A new kind of principal with its own identity.

B

Why today's patterns fall short

OAuth bakes in assumptions that quietly stop being true the moment an agent is the caller.

C

The shape of the answers

How the industry is responding, with AAuth as one concrete, instructive example.

First a quick refresher on the world OAuth was built for.

Part one · the familiar ground

The world we built auth for.

Before agents, who was even calling? A person, and the software they signed in to. Let us re-teach that ground quickly, because every assumption starts here.

The world we built auth for

OAuth's home turf: a person delegates to an app.

A human signs in, consents once, and the app gets a token to act on their behalf. This is the flow OAuth was designed around.

sequenceDiagram autonumber actor U as User participant A as App (client) participant AS as Auth Server participant RS as Resource Server U->>A: use the app A->>AS: redirect to authorize U->>AS: log in and consent AS-->>A: access token A->>RS: call API with token RS-->>A: data

Authorization-code flow: the user consents, the app carries the token.

The world we built auth for

No human at all: one back-end calls another.

The pattern we have refined for fifteen years: Service A calls Service B through a gateway that checks a token. With the client-credentials grant the service speaks for itself; proper workload identity (SPIFFE, WIMSE) does it better, with no shared secret to leak.

  • The service proves who it is with a client id and secret (or a certificate).
  • That identity was registered ahead of time, by a developer, at each server.
  • The token it gets is a bearer token: hold it, and you can use it.

It is tempting to file an agent right here just another service-to-service call. It is not that simple, and the next act is about why.

What's baked in  ⚑

Six quiet assumptions. Watch them.

Every one was the right call in 2012. We will knock each one down in a few slides, once an agent is the caller.

Pre-registered client

The caller is known ahead of time, registered at each server.

Bearer tokens

Hold the token, use the token. Nothing binds it to who carries it.

Scopes as permission

A scope is a standing grant, not the intent of one call.

Redirect and consent

A human at a browser is there to click approve.

TLS does the securing

No signatures. The channel is the security, not the message.

Build-time integrations

The app knows its APIs before it runs.

A short history · how we got here

But first, a little history.

Two of those assumptions, dropped signatures and bearer tokens, were deliberate trade-offs back in 2012. Worth two minutes to see why.

A short history

Plot twist: OAuth 1.0 signed every request.

Proof-of-possession is not a new idea. In 1.0, each request carried a signature proving you held the key. A stolen token was not enough.

oauth 1.0 · signed request
GET /api/photos
Authorization: OAuth oauth_signature="tR3k…", oauth_nonce=…
# the signature proves possession of the secret

A short history

2.0 traded signatures for TLS and bearer tokens.

Signing was painful, browser crypto was weak, and certificates were costly. So 2.0 dropped signatures and leaned on the secure channel instead.

OAuth 1.0

Sign the message

Security at the application layer. Every request proves possession. Powerful, but fiddly to implement.

OAuth 2.0

Secure the channel

Security moves to the transport layer (TLS). The token becomes a bearer credential. Simpler to adopt, weaker by default.

"OAuth 2.0 is a bad protocol. WS-* bad." Eran Hammer, lead editor, on resigning from the spec · 2012

A short history

A stolen access token still works. Nothing binds it to who holds it.

Intercept the booking API's access token, or find it in a log, and you can book flights and charge the card on the user's account. Fine for a fixed backend; the core liability for an agent that carries tokens across services  ⚑

A short history

A framework needs profiles. A protocol does not.

OAuth 2.0 is a base that only becomes usable once you bolt on extensions and pin the choices with a profile.

PKCEDPoPPAR RARJARJARM Token ExchangemTLSOIDC FAPIDevice Flow
  • OpenID Connect, the identity layer almost everyone uses, is itself a profile on top of OAuth.
  • "We use OAuth2" is never enough. You must also name the flow, PKCE, the endpoints, the profile.
  • A framework is hard to conformance-test. A protocol is not.
  • Guardrail: OAuth is conformance-tested, but only its profiles (OIDC, FAPI). You test the profile, not bare OAuth.

Part two · the new caller

Now an agent is calling.

Everything so far assumed software a person registered ahead of time. Agents break that assumption on nearly every axis.

Enter agents

An agent is not a pre-programmed app.

It decides what to do, and what to call, in the moment. The developer wrote the goal, not the path.

  • Autonomous: it acts toward a goal without a coded script.
  • Reasons about context: it interprets, plans, and adapts.
  • Picks its tools at runtime: the next call is chosen as the task unfolds.
  • Long-running: tasks can span minutes, hours, or days.
  • Spawns sub-agents: it delegates pieces of the work to others.

Enter agents

Not a microservice with an LLM.

It is tempting to file an agent under Service A calls Service B. But a model, not code, decides what it does, and that quietly breaks four assumptions the service world was built on.

declared → interpreted

Intent

A service encodes intent in code you can test. An agent interprets a goal at runtime, so the same prompt can act differently each run.

fixed → explored

Paths

A service's branches are baked in. An agent explores tools and APIs to find a path, sometimes one no one coded.

known → discovered

Dependencies

A service integrates with known APIs. An agent discovers tools and authority live; its reach is unknown until it reaches.

service-to-service → on your behalf

Delegation

A service runs with its own account. An agent carries a human's authority down a chain, attributed to every hop.

Framing after Christian Posta · "The Differences Between Microservices and AI Agents"

The reframing

Human? Workload? Or a new layer?

H

Not human

Give it a human identity and it gets the standing of a person without any of the built-in constraints.

W

Not quite a workload

It runs somewhere, so workload identity fits at first. But agents are bursty, ephemeral, and pause and resume across clusters.

A

A new layer

It behaves like an actor. Agent identity sits on top of workload identity, and can collapse into it inside one trust domain, until it cannot.

Keep this it sets up the whole industry comparison later.

The reframing

Delegation is not impersonation.

Do not hand the agent the user's identity. You need both the user and the agent in the picture.

Impersonation

Reuses your token

It calls the booking API with the user's own access token. Every booking is logged as the user, and the agent inherits everything the user can do, not just travel.

Delegation

Acts on your behalf

It calls with its own identity, on the user's behalf (on-behalf-of). Both principals are visible, so you can trace, scope, and revoke the agent on its own.

The reframing

From a rich registry to a runtime principal.

An agent is described in detail somewhere: name, tools, permissions, policy. But at runtime you need one stable, verifiable principal.

Registry: name · tools · permissions Runtime principal Authorize · Attribute · Revoke

That principal is what you use to make an authorization decision, to attribute an action after the fact, and to revoke the agent.

The reframing  ⚑ callback

Every flag just fell.

What we assumed ⚑What's true once an agent calls
Pre-registered clientResources are discovered at runtime; client ids do not travel
Bearer tokensCopied secrets leak somewhere they shouldn't
Scopes as permissionA scope is not the intent of a single call
Redirect and consentDecisions happen mid-task, with no human at a browser
TLS does the securingThe channel is safe, but who is calling is still unproven
Build-time integrationsTool chains assemble live, one call at a time

Where it breaks · five ways

Now, watch it break.

Same booking agent, five concrete failures. Each one is an assumption from Part one collapsing under a single real call.

Where it breaks · 1 of 5

The booking agent needs more than you.

You can request a trip, but charging the corporate card and pulling negotiated corporate fares needs authority your own access token does not carry.

Use your token

Fails, or over-grants

Either the booking fails at the charge, or you are handed broad finance rights you should never personally hold.

Give the agent its own

Scoped to the job

The agent holds its own scoped authority (payments:charge, corporate fares), distinct from any one traveller.

Where it breaks · 2 of 5

Something broke. Who did it?

You said three words. A chain of decisions followed, and one of them charged the card.

You: "book my trip" Agent plans Payment sub-agent Corporate card Non-refundable booking

With only the user's token, you are blamed for a decision you never made, by a system you did not directly control.

Where it breaks · 3 of 5

The token rides a chain, hours later.

Agent tasks are long-running and multi-hop. The neat browser-and-session shape of OAuth simply is not there anymore.

  • An access token is passed down a chain: agent, booking API, payment processor, across providers.
  • OAuth can represent the chain (RFC 8693 act claims) but the spec says prior actors are informational only, never enforced.
  • The user's browser session expired hours ago; the fare needs manager approval and no one is at a browser.
  • The agent needs an authorization decision mid-task (approve this fare), not at login.

OAuth's own standard admits it does not enforce the multi-hop chain

Where it breaks · 4 of 5

Same scope. Very different call.

A scope is standing permission. It cannot tell a helpful call from a harmful one, and a hijacked agent stays perfectly in scope.

one scope · two bookings
scope = "bookings:write" # granted, valid
book economy SYD $320 refundablefine
book business SYD $9,000 non-refundabledisaster
# scope cannot tell these apart

Park this letting the resource decide at call time is exactly how AAuth answers it later.

Where it breaks · 5 of 5

A valid identity can take an invalid action.

Zero Trust worked when identity, device, and session were a good-enough proxy for what a caller would do. For agents, identity stops being a proxy for authority.

Zero Trust for humans

Centred on identity

Who is this?  ·  Is the device healthy?  ·  Does the session look normal?

Zero Trust for agents

Centred on delegated authority

Under whose authority?  ·  What was approved?  ·  What are the delegation bounds?  ·  What is the lineage across sub-agents?  ·  Is it still valid at the commit point?

"Identity is still necessary, but it is no longer enough. Zero Trust for agents has to center on delegated authority."Karl McGuinness · on Harish Peri's Zero Trust thread

The transition

You cannot patch your way to a new principal.

People are already bolting fixes on: DPoP, token exchange, MCP with dynamic client registration. MCP's own experience shows the ceiling: agents still get a different client id per server, still hold bearer tokens, and still have no portable identity, no resource identity, and no governance.

Identity has to move from a build-time fact to a runtime, provable, governable thing. A protocol change, not a token change. The thesis · say it here, and again at the close

Part three · the responses

So how is the industry answering?

Several real projects, on a spectrum. The useful question for each: does agent identity collapse into workload identity, or stand as its own layer?

How the industry is responding

Collapse into workload identity, until you can't.

Collapsed

kagent · Uber

Agent per pod. Workload identity is the agent identity.

Collapsible

kagent + substrate

Distinct actors, but holds the three invariants, so it can still collapse.

Layer above

AWS AgentCore

Stable agent ARN above a churning microVM. AWS owns the stack.

Layer above

Entra Agent ID

A specialized Entra service principal. Single vendor, one domain.

Layer above

AAuth

Cloud-agnostic. Bootstraps from workload identity, no central plane.

← collapsed into workload identitya layer of its own →

Framing after Christian Posta · "What 'is' Agent Identity? Human? Workload? A new Layer?"

How the industry is responding

Entra Agent ID: an agent inside Entra.

A specialized Entra service principal, with rich enterprise identity and on-behalf-of flows already in place.

  • A layer above the running workload, not the workload itself.
  • Single vendor (Microsoft), inside one trust domain.
  • A workload identity (e.g. a K8s service account) is exchanged for the agent's token, but the agent stays its own principal.

How the industry is responding

Agent Substrate: runtime actor identity.

Google's actor-sandboxing layer. Actors run in hardened microVM workers, with a registry that keeps their identity stable.

  • Actors are multiplexed into pre-warmed worker pods at runtime.
  • Identity stays continuous across pause, resume, and reschedule.
  • Mainly a runtime and workload identity layer, and still collapsible.

How the industry is responding

AAuth: a cross-domain auth protocol.

From Dick Hardt, an author of OAuth 2.0. A layer above that bootstraps from workload identity rather than replacing it.

  • Self-published identity, aauth:local@domain, with no pre-registration.
  • Works across trust boundaries, with no single central control plane.
  • Designed to coexist with OAuth, not replace it.

The tell everything before AAuth assumed one control plane in one trust domain.

How the industry is responding

Overlapping, but different slices.

ApproachWhat layerTrust scopeThe slice it solves
Agent SubstrateRuntime identitySingle domainIdentity continuity at runtime
Entra Agent IDIdentity providerSingle vendorEnterprise agent identity and OBO
AAuthAuth protocolCross-domainWho, on whose behalf, across boundaries

They are not competitors so much as different cuts of the problem. The one difference that matters: everything except AAuth assumes one control plane in one trust domain.

Part four · a closer look

How AAuth works. Then we run it live.

Four ideas first: its own identity, proof on every request, a server that gets a say, and a broker that speaks for you. Then a demo.

A closer look at AAuth

Every agent gets its own identity.

A cryptographic identifier per instance, bound to a key, published at a URL the agent controls. No portal, no shared secret.

agent identity
id: aauth:travel-bot.7f3c@acme.example
key: Ed25519 public key, at a well-known URL
# verifiable by anyone, no pre-registration

Callback ⚑ these are the client ids that actually travel.

A closer look at AAuth

Every request is signed.

HTTP Message Signatures on every call. A stolen token is useless without the private key. The agent proves possession each time.

signed request · RFC 9421
POST /bookings
Signature-Input: ("@method" "@authority" "@path" ...)
Signature: :k8sd…:
Signature-Key: jwt="eyJ…"

Callback ⚑ this removes the stolen-access-token problem.

A closer look at AAuth

The resource gets a say.

In OAuth the resource server is a passive token reader. In AAuth it signs a resource token describing exactly what it needs.

Agent calls /bookings 401 + signed resource token "here is what I require" Agent gets authorized

Because the resource signs the request, an attacker cannot swap in a different resource. It also prevents the confused-deputy problem and gives the resource a voice in every authorization.

A closer look at AAuth

The Person Server: the user's broker.

The user chooses it. The agent only ever talks to its Person Server, which holds the agent-to-person binding and brokers consent outward.

sequenceDiagram autonumber participant Ag as Agent participant R as Booking API participant PS as Person Server actor U as User Ag->>R: signed request R-->>Ag: 401 + resource token Ag->>PS: present resource token PS->>U: approve this? U-->>PS: yes PS-->>Ag: auth token (user + agent) Ag->>R: signed request + auth token R-->>Ag: 200 OK

Three-party flow: the booking API asks, the Person Server brokers consent.

Live demo · switch to the terminal

Demo: AAuth in the .NET SDK.

Watch three things, the same three from the start.

  • Who is calling. The agent has its own identity. No API key, no pre-registration.
  • On whose behalf. A protected call pauses for consent through the Person Server.
  • Can they prove it. Every request is signed. There is nothing to steal.

Beyond the demo · governance

A mission is context, not authorization.

A natural-language, user-approved, hash-bound statement of intent, like book my Sydney trip under $2,000, propose before booking, checked against a running mission log.

"A mission is not an authorization. It is just an agreed-upon context."Dick Hardt

  • The agent identity sets the ceiling; the mission narrows it at runtime.
  • Scopes and policy still authorize. The mission is an additional contextual gate.
  • Per-call context can narrow what an agent does, never widen it.

Beyond the demo · governance

The resource decides at call time.

Some operations are granted outright; others are conditional and get re-checked against the actual parameters of the specific call.

R3 · per-call decision
quote fare SYD economygranted, proceed
charge $9,000 non-refundablestep up: confirm
# a proposal bound to these exact parameters (amount, fare, card)

Callback this is the answer to break four: intent versus scope, and prompt injection.

Beyond the demo · adoption

A sibling protocol, not a replacement.

You adopt it one mode at a time, and it wraps what you already run. Your read-only flight-search API keeps its OAuth; only the booking-and-charge path needs the full flow.

  • A drop-in for API keys (identity mode) and for OAuth (resource-managed mode).
  • It wraps existing OAuth and OIDC; the four modes are additive.
  • Existing OAuth clients stay put; AAuth onboards a new class of agentic actors.

"OAuth works great where it is deployed. Why break what is working?"Dick Hardt

Wrapping up

An honest status check.

Hold the enthusiasm at the right level. This is a direction, not a finished standard.

  • An early-stage, exploratory IETF draft, moving quickly.
  • An open debate: is durable mission governance a protocol primitive, or a layer above?
  • It coexists with OAuth, by design, rather than replacing it.
  • A handful of exploratory SDKs, including the .NET one you just saw.

Wrapping up

Who is calling. On whose behalf. And the proof on every request.

That is how the booking agent earns the call: its own identity, a bounded mission the user approved, and a booking API that can still say "confirm this charge."

Learn more

The protocol, the explainer, and the .NET SDK used in the demo.