Agent identity and access: why one shared API key breaks SOC 2 and HIPAA
An agent wired in with one shared credential authenticates as itself, not your user — quietly breaking the access controls SOC 2 and HIPAA require. Here's the fix.
Last updated
You wire an AI agent into production and give it a credential so it can call your APIs, your database, your ticketing system. The fast way is one API key, or one service account, shared across every request. It works immediately. It also means the agent authenticates as itself, not as the person who triggered it — and that single design choice quietly breaks the access controls SOC 2 and HIPAA are built around.
This is engineering guidance, not legal advice — your compliance counsel has the final word on what any framework requires of your system. But the gap below is the one that fails an access-control review, and it is infrastructure.
The failure mode: the agent becomes the only identity in the room
A traditional app carries the user’s identity down the stack: Alice signs in, and the query that runs is Alice’s query, with Alice’s permissions, logged as Alice. Wire an agent in front of that stack with one shared credential and the chain snaps. Alice asks the agent for something; the agent calls the database as agent-service, not as Alice. Downstream, every request looks identical no matter who asked. Two things you used to get for free are now gone:
- Attribution. The system behind the agent can no longer say on whose behalf an action happened. Every row read, every record written, is stamped with the agent, not the human.
- Least privilege. A shared credential has to be able to do everything any user of the agent might need — so it holds the union of everyone’s access. Alice’s request runs with Bob’s permissions too, because there’s only one identity and it must cover both.
Neither is a model problem. The model is fine. The identity architecture in front of it is what an auditor will fail.
Why that breaks HIPAA
HIPAA’s Security Rule is explicit about access. The Access control standard at 45 CFR §164.312(a)(1) requires technical policies “to allow access only to those persons or software programs that have been granted access rights.” Its single Required implementation specification — Unique user identification, §164.312(a)(2)(i) — says to “assign a unique name and/or number for identifying and tracking user identity” (45 CFR §164.312, Cornell LII). HHS’s own guidance is clear on why it’s Required: a unique identifier is what lets a covered entity “track specific user activity” and “hold users accountable” for what they do to ePHI.
A shared agent credential is the direct negation of that. When many people’s requests reach PHI through one identity, you can no longer identify or track which user was behind a given access — the exact capability the rule mandates. It undercuts §164.312(b) Audit controls (mechanisms that “record and examine activity”) because the activity all resolves to one actor, and it muddies §164.312(d) Person or entity authentication, which requires verifying that the entity seeking PHI “is the one claimed.” The agent claims to be one service; behind it are twenty people with different rights.
Why that breaks SOC 2
The Trust Services Criteria reach the same place from the other direction. SOC 2’s logical-access criteria (CC6.1–CC6.3) expect three things a shared credential can’t provide: CC6.1 — identify and authenticate users before granting access to protected assets; CC6.2 — register and authorize each new internal or external user before issuing credentials; CC6.3 — grant access by role, under least privilege and separation of duties. One credential that every user’s request flows through was never individually registered or authorized as those users, can’t be authenticated back to a person, and is over-scoped by design because it must serve everyone. An examiner testing CC6 asks you to show that access is per-identity, authorized, and minimal. A shared agent identity fails all three tests at once — not because anyone misconfigured it, but because a shared identity is structurally incapable of passing them.
This is textbook Excessive Agency
None of this is novel; the standards bodies already named it. OWASP lists Excessive Agency as LLM06:2025, with excessive permissions as one of its three root causes — an LLM component granted more downstream access than the task needs. Its recommended mitigation is precisely the fix here: “Track user authorization and security scope to ensure actions taken on behalf of a user are executed on downstream systems in the context of that specific user, and with the minimum privileges necessary” (OWASP LLM06:2025 Excessive Agency). “In the context of that specific user” is the whole game. A shared key does the opposite: it executes in the context of no specific user, with the maximum privileges any user might need.
It gets sharper with more autonomous agents. ISACA’s audit guidance notes that agents can “create new identities to execute tasks” and “make access decisions in real time” with no formal approval step (ISACA, The Growing Challenge of Auditing Agentic AI, Sept 2025). An agent that can mint and assume identities, running on a shared over-scoped credential, is an access-control review’s worst case: broad standing power, no per-user boundary, no paper trail of who authorized what.
The default, the control it breaks, and the fix
| What the agent does by default | The control it breaks | The fix |
|---|---|---|
| Calls downstream systems with one shared key | HIPAA unique user identification; SOC 2 CC6.1 authentication | Carry the initiating user’s identity to the downstream call |
| Runs every request with the same broad permissions | Least privilege (SOC 2 CC6.3; OWASP LLM06 excessive permissions) | Scope each request to the acting user’s rights via token exchange |
| Acts on behalf of many users under one identity | Attribution / audit controls (HIPAA §164.312(b)) | Log the real initiating user, not just the agent |
| Uses a human’s credentials or an admin key for autonomy | Person/entity authentication; separation of duties | Give the agent its own scoped non-human identity |
| Can create or assume new identities freely | Authorization and access-decision governance (ISACA) | Gate identity/permission changes behind human approval |
What the fix actually looks like
Two identities, kept separate:
For actions on a user’s behalf, propagate the user — don’t replace them. When Alice’s request drives a downstream call, the agent should exchange Alice’s token for a downstream one scoped to Alice’s rights — an OAuth on-behalf-of / token-exchange flow — so the database sees Alice, logs Alice, and enforces Alice’s permissions. This is the “execute in the context of that specific user” that OWASP calls for, and it restores both attribution and least privilege in one move.
For the agent’s own autonomous actions, give it a distinct, narrow, non-human identity. When the agent acts on its own (a scheduled job, a background reconciliation), it should carry its own credential — scoped to exactly that task, attributable to the agent as a first-class actor, and never a human’s login or a broad admin key. Any change to what that identity can do belongs behind the same human-approval gate you’d want on any privileged access, per ISACA’s warning about agents making access decisions unattended.
The point in both cases is that the identity in front of your protected data is specific — a real user or a narrowly-scoped agent — never a shared stand-in. That’s what makes each access attributable in your logs (the raw material of the audit trail an agent needs to survive a SOC 2 or EU AI Act review) and what keeps least privilege real instead of a slogan. It’s the same scoped-identity discipline the deploy agent behind this site runs under — short-lived, scoped credentials per run, never a long-lived shared key.
The gap is measurable
Treat this as correlation, not proof of cause — but the direction isn’t subtle. In IBM’s 2025 Cost of a Data Breach report, among organizations that reported a breach of an AI model or application, 97% reported not having proper AI access controls in place (IBM, July 2025). The shops getting hurt are disproportionately the ones that wired AI in without the per-identity, least-privilege access controls that make a feature auditable in the first place. Fixing the agent’s identity model isn’t compliance theater; it’s the same instrumentation that lets you contain a bad request instead of handing it everyone’s access at once.
The work
Getting an agent’s identity right is architecture, not a policy memo: propagate the initiating user’s identity and scope on every on-behalf-of call, give the agent its own least-privilege non-human identity for autonomous work, retire the shared keys, make every access attributable in the logs, and gate any change to the agent’s permissions behind a human. That is the Guardrails and Ownership ground of the production-readiness bar, made specific to identity — the same ground the HIPAA and auditability reviews walk from their own angles.
If you’re wiring an agent into a regulated system and you’re not sure your access model would survive a SOC 2 or HIPAA review, that’s the production-readiness audit: a fixed-scope assessment against the bar — including the identity and access-control gaps above — with a prioritized risk register and a scoped path to close them.
Questions this raises
Straight answers.
- Can our AI agent just use one API key or service account for everything?
- For a demo, yes. For a regulated production feature, that single shared credential is the problem. When every user of the agent acts through the same identity, the systems behind it can no longer tell which human was really behind an action, and the agent holds the union of everyone's access instead of the minimum each task needs. That collapses two things auditors test directly: per-user identification and least-privilege authorization. The agent should authenticate as itself for its own actions and carry the initiating user's identity and scope for actions taken on their behalf — not stand in for everyone with one key.
- What HIPAA rule does a shared agent credential actually break?
- The Access control standard, 45 CFR §164.312(a). Its one Required implementation specification, Unique user identification (a)(2)(i), says to "assign a unique name and/or number for identifying and tracking user identity" — the mechanism that lets you hold a specific user accountable for what they did to ePHI. An agent that reaches PHI through one shared identity on behalf of many users defeats that tracking. It also strains Audit controls (b), which require recording and examining activity, and Person or entity authentication (d). Whether your feature is in scope is a legal determination — this is engineering guidance, not legal advice.
- How do you give an agent least-privilege access without a shared key?
- Propagate the user's identity instead of replacing it. When the agent acts for a person, it exchanges that person's token for a downstream one scoped to what that person may do (an OAuth on-behalf-of / token-exchange flow), so the database and APIs see the real user's scope — exactly what OWASP's Excessive Agency guidance recommends. For the agent's own autonomous actions, give it a distinct non-human identity with its own narrow, auditable credential — never a broad shared key, and never a human's.
- Is a dedicated service account for the agent enough for SOC 2?
- A dedicated identity is better than a key pasted into ten places, but it isn't automatically least privilege. SOC 2's logical-access criteria (CC6.1–CC6.3) expect each user and service to be registered and authorized, authenticated before access, and granted access by role under least privilege. One service account that every user's request funnels through, holding the superset of all their permissions, satisfies none of those cleanly — you still can't attribute an action to a person, and the account is over-scoped by construction.
Production-Readiness Audit
This is the work, not just the writeup.
If this is your situation, the production-readiness audit is where it gets fixed — by the person who wrote this.