cd /news/ai-agents/your-ai-agent-should-be-a-guest-not-… · home topics ai-agents article
[ARTICLE · art-134883] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↓ negative

Your AI Agent Should Be a Guest, Not a Tenant

A security researcher argues that standing credentials held by AI agents are the root cause behind a recent zero-click remote code execution flaw that affected four major AI coding agents and 925 hijacked plugins. The piece cites Exabeam research finding 48 percent of security leaders rank excessive or compromised agent access as their top threat, and proposes scoping agent permissions to specific tasks, resources, and time windows rather than issuing permanent service-account credentials.

by read7 min views1 publishedSep 20, 2026

Why standing credentials are the quiet root cause behind this week's agent security headlines, and what zero standing privilege looks like in practice.

On Thursday, researchers reported a zero-click remote code execution flaw in four major AI coding agents. The attack chain ran through the plugin supply chain, and reports put the number of hijacked plugins at 925. Two vendors still have not released patches.

Buried under that headline is a quieter fact. Every one of those plugins held a standing credential somewhere, ready to be borrowed. The attacker did not need to mint new access. The access was already sitting there, valid around the clock, waiting for someone to ask for it nicely. This week, someone did.

The timing is worth noting. Two days earlier, Exabeam released research showing that 48 percent of security leaders now rank AI agents operating with excessive, compromised, or unintended access as the greatest threat to their organization. Not external threat actors. Not malicious insiders. The agent with a standing key.

Let me give you an example of how we got here.

Somewhere in your infrastructure there is probably an agent with a credential that never expires. Maybe it is a service account for a coding agent with read access to every repository. Maybe it is an API key for an expense agent that can also refund customers, because the refund tool sits behind the same endpoint. The credential was created in an afternoon, scoped by guesswork, and never revisited.

I understand why. Teams hand agents standing credentials because the alternative feels impossible to operate. An agent's tasks are unpredictable; you cannot always pre-scope a grant when you do not know what the agent will need to touch. Debugging is easier when the agent can see everything. And the credential works the same way for a human script as for an agent, so nobody built a second system.

The problem is that a standing credential works at 3 a.m. on a Saturday, in a prompt injection's hands, with no human in the loop. A human with standing admin at least goes home. An agent with standing admin is home all the time, and so is everyone who figures out how to talk to it.

A good analogy is the hotel minibar attendant. You would not hand that person a master key to every room because a guest might occasionally ask for ice. You would give them a way to open one room, for one delivery, for a few minutes. That is what agents need. Not a smaller master key. A guest pass.

Any competent shop already solved this problem for people. A human requests access, it is scoped to the ticket, it expires, and it gets reviewed. Break-glass exists for emergencies, and break-glass sets off alarms. Nobody finds this strange. Nobody calls it friction that must be eliminated.

So the question is why agents get the treatment we would never accept for a new hire on their first day. The answer, I think, is that we built agent identity as an afterthought. We took the service account, a construct designed for long-lived daemons with fixed behavior, and applied it to software that behaves differently every single run. The service account assumes the workload is predictable. An agent is the opposite of predictable. That is the whole point of an agent.

Here is what the alternative looks like. Let me walk through a concrete scenario.

Imagine a reconciliation agent. Every night it matches 40,000 expense receipts against 40,000 ledger entries. It needs read access to the receipts bucket and write access to one reconciliation table, and it needs them between 2 a.m. and 4 a.m. Eastern. That is the grant. Not the whole data warehouse. Not permanent. Not inheritable by the next task the agent picks up.

Yes, this is a theoretical scenario, but it is hardly an unusual one.

Here is what the grant might look like as a signed envelope the agent carries for the duration of the run:

{
  "subject": "agent:reconciliation-prod-07",
  "issued_for": "task:expense-recon-2026-09-19",
  "resources": [
    {"action": "s3:GetObject", "bucket": "expense-receipts-2026"},
    {"action": "dynamodb:PutItem", "table": "recon-results"}
  ],
  "valid_from": "2026-09-19T06:00:00Z",
  "valid_until": "2026-09-19T08:00:00Z",
  "not_transferable": true
}

A few things are worth noting about this example. First, the subject is the agent instance, not the agent class. reconciliation-prod-07 is one run, and its credential dies with the run. A compromised prompt in one run cannot reach into the next. Second, the resources name exactly two actions on exactly two resources. There is no wildcard, no inherited role, no "read everything in this account because the agent might need it." Third, the grant is bound to a task ID and marked non-transferable. If the agent delegates a subtask to another agent, the subtask gets its own grant from the policy engine. Credentials do not get passed along like a hall pass.

The policy engine that issues this grant is doing the same job your existing access request system does for humans. It checks who is asking, what for, and for how long, and it writes down the answer. The difference is speed: this check has to happen in milliseconds, at task start, every time. That means policy as code, evaluated locally, with the decision logged. A document describing who may access what is governance theater. A policy engine that says no in forty milliseconds is governance.

Short lifetimes are doing most of the real work in the design above. The grant expires, and that is what bounds the blast radius when something goes wrong. A zero-click exploit that lands in an agent holding a fifteen-minute grant to read a receipts bucket finds very little to steal. The same exploit landing in an agent with a standing service account finds everything the account was ever given.

Pick lifetimes aggressively. Fifteen minutes for interactive agents that act in tight loops. An hour for batch jobs. A day only for workflows that genuinely cannot checkpoint and resume, and even then, scope them tighter to compensate.

Here is the part people get wrong: renewal is not a refresh. When a grant nears expiry, the agent does not extend the old one. It requests a new one, and the request goes back through the full policy check. That means a permission revoked at 2:47 p.m. stops working at the next renewal, not whenever someone remembers to rotate the key. The failure mode is "fail closed," which is the only failure mode you want for access control.

This also fixes the debugging objection. The complaint is always that short-lived grants make incidents harder to investigate, because the credential is gone by the time you look. But the grant envelope is logged at issuance and at every renewal, with the task ID attached. You get a better audit trail than the standing credential ever gave you, because now every access decision is a timestamped event instead of a key created two years ago by someone who left the company.

If you are reading this and thinking about your own fleet of agents, here is the honest version of the adoption path. You probably cannot answer a simple question right now: which agents hold which standing credentials, and what can each one touch. That gap is the actual finding. Before any of the design above, inventory the standing grants. You will find some that surprise you. Retire the broadest ones first, starting with anything that touches production data or money movement.

Then make new agents JIT from birth. It is far easier to start agents on just-in-time grants than to migrate a standing credential that five teams have quietly built dependencies on. The policy engine can be small at first. Even a hardcoded allowlist evaluated at task start is better than a service account that lives forever, because it has an expiry and a task binding. Grow it into real policy as the fleet grows.

One more honest caveat. This does not stop prompt injection, and it does not stop zero-click vulnerabilities. Those are real problems that need their own answers. What zero standing privilege does is decide how much those problems cost you when they happen. A vulnerability in an agent with no standing access is an incident. A vulnerability in an agent with standing access to everything is a breach. The headlines this week are breaches, and the standing credential is why.

The practical consequence is simple. Somewhere in your stack there is an agent holding access it does not need right now, for a task it is not currently doing. That credential is doing nothing for you and everything for an attacker. Take it away, and hand the agent a guest pass instead.

What is the agent in your stack with the most access right now, and could you tell me what it can touch without checking?

── more in #ai-agents 4 stories · sorted by recency
── more on @exabeam 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/your-ai-agent-should…] indexed:0 read:7min 2026-09-20 ·