cd /news/ai-agents/zero-standing-access-for-ai-agents-l… · home › topics › ai-agents › article
[ARTICLE · art-160105] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Zero Standing Access for AI Agents: Let Users Lend Access, One Session at a Time

A developer has proposed making AI agents a first-class principal in IAM, built on the rule that an agent owns no access and instead borrows it from the user it works for, one request at a time, with consent, for the current session only, and never exceeding that user's own permissions. The design adds agent templates, agent sessions, grants, access requests, consent rules and an activity log, and keeps agent grants in a separate table that dies with the session so standing access cannot exist by accident. The post notes that as of October 2026 no finished standard for agent access exists, though vendor approaches converge on agents getting their own identity, delegation via token exchange with the agent recorded in the act claim, and short-lived credentials.

by read11 min views1 publishedOct 29, 2026

Agents are doing real work in our products now. They read records, draft emails, file tickets and reconcile invoices. To do any of that they need access, and when it's time to give it to them, most teams reach for one of two tools. Both are wrong.

Option one: a service account. The agent gets its own credentials with a fixed set of permissions. It works, but it's standing access that no user ever agreed to, it isn't bound to any user, and every action shows up in the audit log as "the robot did it".

Option two: let the agent act as the user. Pass the user's token through, or mint one that impersonates them. Now the agent can do everything the user can do. A task that needed one key gets the whole keyring.

I think agents deserve to be a first-class principal in IAM, next to users and service accounts, built on one rule:

An agent owns no access. It borrows access from the person it works for, one request at a time, with that person's consent, for the current session only, and never more than that person has.

The rest of this post is what that rule looks like in practice: the entities IAM needs, agent templates, a permission catalog that IAM hosts as a tool, three user journeys with wireframes, and the parts I'm still arguing with myself about.

TL;DR

As of October 2026 there's no finished standard for agent access. There is a lot of convergence, though.

Standards and guidance

What vendors ship

sub and the agent as act. The convergence is real: agents get their own identity, delegation goes through token exchange with the agent recorded in act, credentials are short-lived, and some permissions are blocked outright. What's still mostly missing is the part in the middle. What happens between "the agent asked" and "the agent got it"? Who consents, to what, for how long, and what do subagents inherit? That's the part this post is about.

Here's how an agent compares with the two options we have today.

Service account Acting as the user Agent
Acts for Itself A user A user
Access when it starts Whatever an admin granted All of the user's access None
Who decides its access An admin, up front Nobody The user, per request
Bounded by the user No Equal to the user Always at or below the user
How long access lasts Until someone changes it The token's lifetime The session
Audit shows The service account The user The agent, the user and the session
Stop one run No No Yes

To support this, IAM and user management need a few new things: an agent template (what a kind of agent may ever ask for), an agent (a deployed agent with its own credential), an agent session (one run for one user), grants, access requests, consent rules and an activity log.

One design choice matters more than it looks: none of the existing grant tables (role assignments, group memberships, user permissions) ever point at an agent. Agent grants live in their own table and die with their session, so standing access for an agent can't exist even by accident.

Most systems have more than one kind of permission, and an agent should be able to borrow each of them, with the same rules applied to all.

Kind Controls Example
API permissions Which endpoints and actions it can call Accounts API · Read
Data permissions Which records and fields it can see Accounts in my region
Asset permissions Which objects it can open Q3 pipeline dashboard · View
Tool and outbound permissions Which tools it can run and where data can go Send email to customers
Never delegable Nothing an agent can ever get IAM admin rights, emergency access, managing agents or consent

Your system may have more kinds, such as feature flags, billing actions or workflow approvals. The rules don't change. Each kind is a type of grant with its own enforcement point.

An agent template is a reusable definition of one kind of job. It holds:

The ceiling stops an agent from overreaching. It doesn't make the agent ask well. Left alone, an agent will often request its whole ceiling up front, because that's the easiest way to never be blocked. The context is there so the agent does the analysis every time: what's the smallest set of access this task needs, when is sensitive data actually justified, and when should it give access back.

Ask only for accounts in the renewal window, never the whole book. Prefer read access. Ask for contract pricing only when the user asks about price. Release access as soon as a brief is done.

Organizations can turn a template on and narrow it, but never widen it. A new version that widens the ceiling asks users for consent again. A version that only narrows it doesn't.

Here's a problem I didn't expect. People building agents don't know the permission model, and agents guess. IAM is the only system that knows what permissions exist, what each one unlocks, how risky it is, which data is sensitive and what's never delegable.

So IAM should publish that knowledge as a tool. iam.describe_permissions(task) searches the catalog for a task. iam.explain(permission) says what a permission unlocks, how risky it is, where it's enforced and whether an agent can have it. Builders use it to write ceilings. Agents use it at run time to plan the smallest request. Security reviewers use it to see what a new template version adds.

The same IAM tools give the agent its access during a session:

Tool What it does
iam.describe_permissions(task) Finds the permissions that fit a task, with risk and sensitivity
iam.request_access(items, reason) Asks for access for this session. Each item is granted, refused or sent to the user
iam.my_access() Lists what this session holds right now
iam.start_subagent(template, read_only) Starts a subagent from an allowed child template
iam.release_access(items) Gives access back early
iam.end_session() Ends the session and every subagent, and revokes all grants

The app makes these calls for the agent and holds the tokens. The model sees each result, never a token.

The user opens a three-pane app: sessions on the left, the chat in the middle, and the session's access on the right.

Step 1: the session starts with nothing. The user types the task and picks a mode from the message box. The app exchanges the user's token, its own credential and the template for a session token that carries no permissions at all.

Step 2: the agent asks. To find this quarter's renewals, the agent calls iam.request_access for three items: an API permission, a data permission and an asset permission, with a reason. IAM checks each item: it's inside the template's ceiling, the user has it right now, and it isn't on the never-delegable list. No saved rule covers these, and the mode is Ask, so the call comes back as a prompt in the chat.

Step 3: the user approves. They choose Always allow. IAM records three grants on the session and three rules, then issues a fresh token with exactly those permissions. The decision only counts because it arrives with the user's own token. An agent can't approve its own request.

Step 4: the agent works, and starts a subagent. It calls the accounts API with its own token. Then it starts an email drafter subagent, read-only. The drafter inherits the three grants as read-only, asks for its own "Email templates · Write", and gets it once. That grant stays with the drafter and doesn't flow up to the parent.

Step 5: a sensitive request, and a change of access. The drafter asks for contract pricing. Sensitive items prompt in every mode and can never be saved as Always allow, and the user denies it. That afternoon the user loses access to the pipeline dashboard. At the next token refresh, 15 minutes at most, the agent loses it too. Nobody had to touch the agent.

Step 6: the session ends. The agent calls iam.end_session, or the user clicks End session, or it expires. The session and its subagents are revoked. The saved rules stay.

The user starts a new session, and it holds nothing. The agent asks for the same three items. Two match saved rules and are granted with no prompt. The dashboard has a saved rule too, but the user no longer has access to it, so it's refused. A rule never grants more than the user has.

Later, someone in compliance asks what the agent accessed for this user last week. The activity log answers per session: what was asked, who decided and how (prompt or rule), what was granted and what was called. When the template ships a version that widens its ceiling, users are asked again once.

If you've used an AI coding tool, you already know the shape of this. The order matters. The template's ceiling, the user's current access and the never-delegable list always win. Then deny, ask and allow rules apply, and only then the mode. The mode is stored on the server's session record. If the agent could send it with the request, a prompt-injected agent would simply claim bypass.

The mechanics are mostly standard. The app does an OAuth 2.0 Token Exchange (RFC 8693) when the session starts, and the agent's identity rides in the act claim, with one more nested act for each subagent level. Tokens live 15 minutes at most and are re-issued after every grant. The user's current access is re-checked at every issue, so losing a role removes it from the agent within one refresh. Revoking a session bumps a version number that every token carries.

Each kind of permission is enforced where it already lives:

Two lessons that weren't obvious until I worked through them:

Risk Guardrail
Prompt injection makes the agent ask for broad access Template ceiling, deny rules, the never-delegable list, the reason shown in every prompt, and a rate limit on requests
The agent approves its own request Decisions only count with the user's own token
The agent claims a more permissive mode The mode lives on the server
Escalation through admin tools IAM admin rights are never delegable, so an agent can't raise its own user's access
Subagents combine into something no template allows Review a template together with its child templates, and keep tool and outbound permissions in the ceiling
Data leaves through a tool IAM doesn't govern Tool and outbound permissions are a kind of grant, enforced by a tool gateway
Background agents with nobody at the screen Push approvals to the user's phone (CIBA) instead of letting saved rules quietly become standing access
Consent fatigue Modes, saved rules, and templates whose context keeps requests small

The convention, in RFC 8693 and in what Okta and AWS ship, is sub = the user and act = the agent. It reads naturally: the agent acts on behalf of the user.

I lean the other way: sub = the agent session, with the user as on_behalf_of. The reason is failure mode. In a large system, some service somewhere will look up permissions by sub. With the user in sub, that service hands the agent the user's full access. With the session in sub, it finds nothing and fails closed.

The cost is that standard libraries and MCP clients expect the convention. If you follow it, you need confidence that every service checks the token's own permissions and never re-derives them from sub. I'd love to hear which way you went and why.

Agents will soon outnumber the people in most identity systems. Least privilege has always been more of an aspiration than a default, because people's tasks are hard to bound. Agents are different: a session gives us a natural boundary, and a chat gives us a natural place to ask. Let's use both. Start every agent at zero, let the user lend what the task needs, and take it back when the session ends.

Sources

── more in #ai-agents 4 stories · sorted by recency
── more on @iam 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/zero-standing-access…] indexed:0 read:11min 2026-10-29 · —