Skip to content

← All posts

September 30, 2026

Acting As You, Not For You 

Acting as you, not for you

Why per-user credentials for AI agents — not one shared bot token — decide whether your audit trail names a person or a robot 

Open your version control system and sort recent commits by author. Near the top, by volume, sits an account that is not a person: automation-bot. ci-service. platform-integration. Nobody remembers who created it. Its token hasn’t been rotated in a while. And after three years of absorbing whatever each new use case needed, it has more access than any engineer you employ. 

That account is about to become the identity of every AI agent you deploy — unless you decide otherwise, on purpose. 

It is already a crowded population. CyberArk’s 2025 identity security research found machine identities outnumber human ones by more than 80 to 1, and AI agents are about to grow that count faster than any access review can follow. Which makes this the least-discussed, most consequential decision in an agentic AI rollout. Not which model. Not which framework. Whose credential does the agent use when it actually does something? 

New to the series? Part 1 shows why governance, not capability, stalls enterprise AI. Part 2 gives every agent a name. Part 3 limits which agents it may call. Part 4 makes human approval durable. Part 5 follows the agent out of your platform and into everyone else’s. 

THE 90-SECOND VERSION 

  • The default is one shared credential per system — one repository token, one chat bot, one API key — used by every agent on behalf of every user. 
  • Two failures follow. Attribution collapses: every commit, message and record lands under the bot, so the audit trail ends at a service account. Blast radius maximises: whatever that credential can reach, every user of the agent can reach through it.
  • The fix separates two questions that are usually tangled: whose identity does this call use, and where does that credential live? Kept apart, a mode explosion shrinks to three values and four storage schemes. 
  • With per-user (per-principal) credentials, the agent acts as the person who asked — through an account they connected, can revoke themselves, and that carries only their own access.
  • The strongest proof is subtractive: the agent holds no vendor credential and has no network route to the vendor, yet the work completes — authored by the person who consented.

Why a shared service account fails AI agents 

There are two distinct failures, and organisations usually notice the second one first. 

Attribution collapses

Priya’s team ships an agent that files vendor discrepancies as tickets. Every ticket is authored by finance-automation. Three months and eleven hundred tickets later, a manager asks which came from Priya’s team and which from the procurement pilot. The tracking system cannot say. The answer might exist in application logs — if they were retained, if anyone correlates them — but the system of record, where the work actually lives, has one author for all of it. 

That is not a reporting nuisance. In any regulated process, who did this? is the first question of every investigation and every audit — and the answer is a robot’s name. 

Blast radius maximises

A shared credential has to be the union of everything anyone needs. Finance needs write access to finance records; procurement needs to read contracts; support needs to update tickets. The bot ends up holding all three. If the support agent can be induced — by a prompt injection, say — to make a finance call, the credential permits it, because credentials do not know which use case they are serving. 

Worse, the reach is identical for every user. A contractor with three days left and read-only access to one project asks the agent a question. The agent answers with the bot’s credential, which can see everything. The contractor’s own limited access is never consulted. 

This is exactly the pattern OWASP flags as Excessive Agency (LLM06:2025) in its Top 10 for LLM applications: an extension meant to act for an individual user that reaches downstream systems through a generic high-privileged identity. And with compromised credentials the initial access vector in 22% of breaches in Verizon’s 2025 Data Breach Investigations Report, a long-lived, over-scoped bot token is precisely the asset attackers go looking for.

An agent using a shared service account can act for a person, but never as them. Every action lands under the bot — and anything the bot can reach, every user of that agent can reach. 

Why a shared service account fails AI agents

The design mistake: treating two questions as one 

Most attempts to fix this get complicated fast, and the reason is conceptual: teams conflate two questions that are genuinely separate. 

The first is whose identity does this call use? The organisation’s, as a corporate actor? The person who asked, so the work is theirs? Or the agent’s own, because it is working on its own behalf — a scheduled reconciliation with no human requester? 

The second is where does that credential live? In an administrator’s encrypted store? In an account a particular person connected through a consent flow? Supplied by the runtime environment? Nowhere at all, because the endpoint needs no authentication? 

Treat these as one question and you get a combinatorial explosion — a mode for every plausible pairing, most of which nobody wants, each needing its own code path. Teams get partway in, realise the shape is wrong, and ship “shared token, plus a special case for GitHub.” 

Keep them apart and the whole thing collapses into something small. 

The design mistake- treating two questions as one

Whose identity takes three values. The organisation — a corporate action, correctly attributed to the company. The person who asked — the agent acts as them, under their name and with their access. The agent itself — autonomous work with no human requester, where the agent is properly the actor. 

Where the credential lives is a reference that can point at different stores: an administrator-held organisational secret, an account a specific principal connected, something the runtime supplies, or nothing at all for an open endpoint. 

The elegance is in what this makes unnecessary. A shared connected account — one team mailbox that several agents use — needs no new identity mode. It is an ordinary organisational binding pointing at a different kind of store. No new concept, no new code path, and every existing call site keeps working. 

Three objects, deliberately kept apart 

The data model holds three things. Keeping them separate looks like over-engineering — right up until you skip it. 

  • Organisational credential — administrator-managed configuration. Long-lived, no refresh cycle, a few dozen per organisation.
  • Provider registration — your organisation’s own application registered with a third party: the client ID and secret that make consent flows possible. One per provider.
  • Connected account — one principal’s account at one provider, owned by that principal (a person, an agent or a service identity). Refreshable, revocable and numerous: potentially every person times every provider.

The temptation is to fold connected accounts into credentials, since both are secrets. Resist it. They have different owners, different lifecycles and wildly different cardinality. The first time a 500-person organisation connects a provider, an admin screen designed for a few dozen entries becomes unusable — and a self-service action ends up behind an administrator’s permission, which defeats the point. 

Separate stores, one resolver: whatever reads a credential reference does not care which store answered. Two further decisions are worth naming. 

Connected-account secrets get their own encryption key. They are a different class of material with a different blast radius; sharing a key means one compromise takes both. The separation costs one configuration value. 

There is no platform-owned application. Each organisation registers its own application with each provider. It is more setup, and it is not negotiable: a platform-owned app would put the vendor’s name on every consent screen your employees ever see, make the vendor a party to your relationship with that provider, and let one platform-level revocation sever every customer at once. 

When the agent should be the actor: non-human identity done right 

Because the identity axis has three values rather than two, it solves a problem most organisations currently solve badly. Some work genuinely belongs to the agent: a monitoring agent that files alerts, a reconciliation that runs nightly, an integration that maintains a system of record. Attributing that work to a person is wrong. It puts their name on activity they did not initiate and cannot review at volume — and it breaks the moment they change role. 

So an agent can hold a connected account of its own: a genuine non-human identity in the third-party system, distinct from human accounts and from the shared bot it replaces. The difference is specificity. The old bot was one identity for all automation, accumulating permissions from every use case that ever needed one. A per-agent service identity holds only what that agent’s job requires, is created deliberately by a named administrator, and sits in the members directory where an access review will find it. 

This closes the loop Part 2 opened: an agent’s authority inside your platform should be granted, not accumulated. Part 3 applied the same least-privilege principle to which agents may call which. Part 5 applies it outside the platform, to third-party systems with their own permission models. You need every half. An agent perfectly scoped inside your platform that presents a shared bot token outside it has simply moved the problem somewhere your governance cannot see. 

Standards bodies are arriving at the same place. NIST’s National Cybersecurity Center of Excellence has opened a project on software and AI agent identity and authorization, because identity patterns built for people and static workloads were not designed for autonomous actors. 

If you cannot name the human whose work an agent is doing, give the agent its own identity — never let it borrow a generic one. 

Consent is the easy part — the edges are the product 

The connection flow is a standard OAuth consent handshake with the modern protections: a per-attempt PKCE challenge so an intercepted response cannot be replayed, single-use state, and — where the provider supports it — automatic client registration, all in line with the OAuth 2.0 Security Best Current Practice (RFC 9700). 

The interesting engineering is not the handshake. It is everything around it — and that is where a demo becomes a product. 

  1. People connect their own accounts- if connecting requires an administrator, self-service dies and adoption follows it. The account owner starts the connection, sees exactly what is being requested, and disconnects whenever they like — no ticket. 
  2. One missing connection must not disable everything else- An agent with four connectors, one of them unconnected, should still do the other three. The naive build refuses the whole request. The right one exposes the unavailable connector’s operations as tools that exist but explain, when called, exactly why they cannot proceed — so the model routes around the gap and tells the person what to fix. 
  3. Say precisely what is wrong- “Not connected” is the wrong message when the truth is “your access expired”, “you approved read access but this needs write”, or “an administrator has not registered this provider yet”. Each has a different fix and a different owner. One generic failure sends everyone to the help desk. 
  4. Ask whose identity before asking for a credential- An administrator configuring a connector for per-person use should not be prompted for a token — there is no organisational token in that arrangement. The order of the questions is part of the design. 
  5. Request the narrowest scopes, and step up only when needed- The Model Context Protocol’s security best practices warn that omnibus scopes widen blast radius and blur audit trails, and they rule out passing tokens straight through to downstream APIs. The same discipline applies to every agent integration, MCP or not. 

THE PROOF THAT CONVINCES A SECURITY TEAM 

The demonstration worth running is a subtraction, not an addition. 

Deploy an agent with no vendor credential in its environment and no network route to the vendor at all. Ask a person to connect their own account. Then give the agent a task that needs that vendor. 

The work completes. The record in the vendor’s system names the person who consented as the author — not a bot, not the platform, the person. Inspect the agent directly and it holds nothing: no token, no key, no reachable path. 

That result is the argument. The agent could not leak a credential it never held, and could not exceed the person’s access, because the person’s access is all it ever used. You do not have to trust the agent’s behaviour — its behaviour was never what constrained it. 

What it costs — honestly 

  1. Setup is genuinely more work– Registering an application per provider per organisation, mapping scopes and getting people to connect their accounts takes more effort than pasting one token into one field. It front-loads work that a shared token merely defers — until the incident. 
  2. Not every provider cooperates– Consent implementations vary. Some return an account-specific endpoint you must then use; some issue user tokens shaped differently from application tokens; some require manual approval before an app may request certain permissions at all. Per-provider templates and adapters absorb this so the person configuring does not have to — but the variation is real and it does not go away. 
  3. Some work should stay organisational- A nightly reconciliation has no human requester. A compliance archive should be the company’s action, not an individual’s. Per-user credentials are the right default for interactive work, not a universal rule — which is exactly why the identity axis has three values rather than one. 

WHAT TO TAKE AWAY 

  • Decide whose credential your agents use deliberately — before the shared service account becomes load-bearing. 
  • Shared tokens destroy attribution and maximise blast radius. Both failures are structural; better agent behaviour fixes neither.
  • Separate whose identity from where the credential lives. Conflating them causes the mode explosion that stalls most attempts.
  • Let people connect and revoke their own accounts, degrade gracefully when one connection is missing, and say precisely what is wrong.
  • Give autonomous agents their own narrowly scoped identity instead of a generic bot.
  • The strongest security argument is subtractive: no credential, no route — and the work still gets done, under the consenting person’s name.
← All posts