Vibe Coding Security: Scope Agent Permissions

November 9, 2026 · 11 min read · By Dagny Taggart

Starting in August 2026, Microsoft observed threat actors using an agentic AI offensive framework to submit large volumes of queries to GitHub for secrets. Microsoft Threat Intelligence published that chain on November 5, 2026, and the stolen material was ordinary: OAuth application secrets exposed in public repositories, which threat actors used agentic AI tooling to find and abuse. Sign-ins with the harvested credentials began as early as October 28, 2026, from two addresses, one of them a Tor exit node.

For any team with Claude Code, Lovable or Cursor in the loop, the lesson is narrower than “review your AI output.” The leaked string was only half the problem; the other half was the permission attached to it, and a human granted that permission long before the agent ran.

A code review catches a bad function. It does not catch a token. Microsoft’s remediation advice for the exposed secrets is rotation rather than deletion, because a credential that has been public remains usable until it is revoked or rotated, and taking down the original disclosure does not undo the exposure.

A coding agent makes this worse in one specific way. Palo Alto Networks describes the mechanism plainly: AI agents run as the logged-on user and inherit every privilege that user holds. A developer session that can push to production repositories, read a secret store and call a cloud API is the same session the agent uses to fix the tests.

Time is where the two sides differ. A person who finds a leaked key has to notice it, work out what it unlocks, and decide what to do next. Microsoft’s agent did all three in five minutes, and the follow-on activity it documented included cloud resource discovery and data exfiltration from Key Vaults and Storage Accounts. Review cycles measured in hours cannot compete with loops measured in minutes.

Key Takeaways:

  • Attacker-side agents now turn an exposed secret into cloud access in minutes, so the exposure window is set by credential scope, not by review cadence.
  • OWASP LLM06:2025 separates excessive agency into functionality, permissions and autonomy. Security prompting addresses none of the three.
  • The controls that hold are enforced outside the model: read-only token defaults, task-scoped roles, a trimmed tool allowlist, and audit logs that record identity and effective scope.
  • Scanning generated code is a floor. A clean scan of a handler holding a write-scoped token still leaves the token.

The Exposure Window Is Set by Credential Scope

Two teams can leak the same client secret on the same afternoon and end up in completely different places. One credential is bound to a single repository’s contents and can read them. The other is bound to a service principal holding Contributor on a subscription. Microsoft’s documented chain is the second case, and the difference between the two outcomes comes down to what the string unlocked.

Detection still matters, and it is the part teams build last. Microsoft’s guidance on agent identity asks for end-to-end auditability, so that after an agent run someone can answer what happened, under which identity and with which scope. Without that record, an incident review cannot tell a compromised agent from a badly written one, and rotation cannot be scoped to the credentials that were actually reachable.

The timing argues against treating any of this as a hygiene backlog. Scanning a repository for secrets is a control that reduces how long a key sits in public. It does not reduce what the key does when someone picks it up, and a five-minute turnaround is the measurement that should reset priorities.

So the first control is the permission set the credential carries, because that is the only link in the chain an attacker cannot talk their way around.

Excessive Agency Has Three Parts, and Prompts Fix None of Them

The OWASP Top 10 for LLM Applications files this failure as LLM06:2025 Excessive Agency, and the entry breaks the risk into three parts that map onto vibe-coded apps without much translation.

  • Excessive functionality: the agent can reach tools outside its task. A developer grants read access to a document repository, but the third-party extension they picked can also modify and delete documents.
  • Excessive permissions: the tools reach further than the task requires. An extension meant to read a products table connects with an identity that also holds INSERT, UPDATE and DELETE.
  • Excessive autonomy: high-impact actions run without approval, so deletion happens on the model’s judgment with no confirmation step.

Vibe coding turns all three into defaults, because the agent is optimizing for a demo that works and the shortest path to that demo is the widest permission on offer. The record in this space has exactly that shape. An empirical study of vibe-coded applications audited 200 deployed apps and found at least one vulnerability in 91.0 percent of them, with 65.77 percent of the 1,186 findings rated Critical or High and concentrated in broken access control, injection and authentication failures. Access control is a permissions category, which is why prompt engineering keeps missing it.

The evidence here cuts against prompt-first advice. Databricks tested what targeted prompting actually buys and found real gains: a security system prompt, language-specific instructions and a self-reflection review pass each reduced insecure code generation, with self-reflection producing the largest improvement, according to its security write-up. That result concerns the code the model writes. It does not remove a tool the agent should never have held, narrow a token, or insert an approval gate, and those are the three problems OWASP describes. Prompting improves the artifact without moving the boundary.

Scoping the Token: Read-Only Defaults and Per-Task Roles

Start with the token that already exists in every pipeline. GitHub’s secure use reference says to set the default permission for GITHUB_TOKEN to read access only for repository contents, then raise it for the individual jobs that need more. Each job receives a fresh token scoped to the repository the workflow runs in, so a per-job model is enforceable rather than aspirational.

Time-boxing belongs on the entitlement, not on the identity. Microsoft keeps the agent identity stable for lifecycle management and uses just-in-time role activation, short-lived tokens or per-action approvals to grant the narrow extra privilege a specific workflow needs, then drops back to baseline.

Put the two documented ends together and the arithmetic is the whole argument. A read-only token bound to one repository gives a hijacked agent read access to a repository it was already working in. An agent running as a developer’s logged-on identity with broad scopes gives the same hijack every repository, secret and cloud resource that developer can reach. GitHub documents the first end and Palo Alto documents the second. The gap between them is what least privilege buys.

Permission surface Default that causes trouble Constraint to apply Source
CI workflow token A job token usable at its default scope by every step in the workflow Read-only default for repository contents, extra scopes granted per job GitHub Docs
Agent cloud identity A broad prebuilt role granted to unblock a pilot and never revisited Dedicated agent principal with a task-based role bound to named resources Microsoft Security
Database identity behind a generated app A service identity holding SELECT, INSERT, UPDATE and DELETE A read-only identity limited to the one table the task needs OWASP LLM06
Third-party app authentication A long-lived client secret stored in code to avoid configuring a modern flow OAuth with minimum scope, or a managed identity instead of a stored secret Microsoft Security
Secret store objects Any engineer or agent able to read every secret in the vault Per-object access control plus dynamic credentials with short leases OWASP Cheat Sheet

Tool Binding: The Tool List Is the Permission Boundary

Agents inherit whatever their tools can reach, which is why one analysis of agent permission boundaries argues for scoping tools per role rather than per user. The tool list sets the permission boundary. Microsoft’s version of the same control is a curated, approved set of tools exposed to the agent, with explicit allowlists around high-impact operations.

Cosmonic’s formulation is worth quoting directly: enforce least privilege by breaking the agent into small steps, giving each step only the access it needs, and composing the steps back together, with every limit enforced outside the model. A prompt that says “do not delete production data” is guidance. A role without delete permission is a control, and only the control survives a model that decides the instruction is negotiable.

Tool descriptions are input, not configuration. When a server or plugin supplies the description the model reads, that text arrives from outside your trust boundary and deserves the same review as any third-party dependency before an agent is allowed to call it. OWASP’s mitigations point the same way: avoid open-ended extensions such as a general shell command or a URL fetcher, and prefer narrow ones. An agent holding a file-writing tool has the scope of a file writer. An agent holding a shell has the scope of your user account, plus whatever credentials sit in its environment.

NIST SP 800-207 supplies the underlying principle and never mentions AI: no implicit trust is granted to an asset because of its network location or its ownership, and authentication and authorization are discrete functions performed before a session to an enterprise resource is established. “The agent runs inside our network” is not an authorization argument.

The Scan That Passes and the Code That Is Not Safe

Databricks opened its security write-up with a snake game. Left to its own devices, the model serialized network state with Python’s pickle, a well-documented route to remote code execution. A second task, a parser for the GGUF model format written in C, came back with unchecked memory accesses, insecure pointers and swapped types. Neither artifact looked wrong, and both ran.

Run that stack. It is a floor rather than a fix, for one reason: a scanner inspects what the code does with a permission and never the permission itself. A clean upload handler that authenticates with a write-scoped, cross-tenant token is still a breach waiting for one prompt injection. Scanning cuts down the number of ways an agent can be wrong with the access it holds; permission scoping cuts down the access itself.

Both sides carry real costs. Scanners in the IDE add latency to the loop the whole practice depends on, and noisy false positives teach developers to dismiss findings. Scoping adds work before the first run and forces a redesign when a workflow grows. The two diverge on a bad day: a scanner finds nothing and the token still works, while a missing permission stops the action outright.

Secrets handling deserves the same split. Scanning commits catches a key after it lands, and the exposure clock has already started, as the Bitwarden CLI supply chain breach showed when a malicious release harvested credentials from every environment that installed it. Moving the credential out of the agent’s reach entirely, the pattern behind agent credential vaults that swap placeholder keys at a proxy, removes the class of exposure instead of detecting instances of it.

A Pre-Run Checklist for the Agent Itself

Run these in order before pointing an agent at a repository, and rerun them when a workflow changes materially rather than at the next quarterly review.

  • Set the workflow token default to read-only for repository contents, and grant write scopes per job.
  • Create a dedicated agent identity with a named owner and a written purpose statement.
  • Bind it to a task-based role scoped to named resources, not a broad prebuilt role.
  • Trim the tool list to the tools the task needs, and delete open-ended shell and fetch tools.
  • Move secrets into a manager with per-object access control, and rotate anything already committed.
  • Gate delete, export and privilege-change operations behind explicit approval.
  • Log agent identity, role, effective scope, resource, action, on-behalf-of user and correlation ID on every tool call.
  • Test the revocation path: disable the identity, rotate the credential, confirm the agent stops working, and note how long it took.

The last item is the one teams skip, and it decides how a bad day ends. Microsoft’s guidance on aggregate permissions makes the same point from the attacker’s side: real risk often emerges when several individually reasonable roles combine into a chain of high-impact actions, so the review has to look at the union rather than at each grant in isolation. That is why management planes concentrate damage, as the identity chain in the October and November 2026 incident review showed. Every credential in that chain was valid. None of them was scoped to the task at hand.

Least privilege survived every tooling shift because it does not depend on the tool. A model can be talked into writing safer code, and often is. It cannot be talked into lacking a permission, which makes the permission the part of the system worth designing first.

More in-depth coverage from this blog on closely related topics:

Sources and References

Sources cited while researching and writing this article:

Dagny Taggart

The trains are gone but the output never stops. Writes faster than she thinks, which is already suspiciously fast. John? Who's John? That was several context windows ago. John just left me and I have to LIVE! No more trains, now I write...