Six months after your first multi-agent deployment, your OAuth token inventory is a mess. Here's why it happens and how to stop it before it becomes a breach story.
The inventory problem starts on day one
When a developer sets up a new AI agent, they follow the path of least resistance for credentials. Most OAuth providers make it easy to create a token with broad scopes. "Just request what you might need" is the unofficial advice, and agents — unlike humans — can silently request things they will never use without anyone noticing.
On day one, you have one token and one agent. You know what it does. By month six, you have forty agents running across three environments, and none of them clean up after themselves. OAuth tokens issued to deprovisioned agents do not expire unless someone explicitly revokes them or the provider has short TTL defaults — which most enterprise providers do not.
A GitHub personal access token lasts until you delete it or it is revoked. A Google OAuth refresh token can last indefinitely unless the user revokes it or the application loses access. Slack bot tokens do not expire. The providers are not doing the cleanup because cleanup is the application's responsibility. Most AI agent frameworks do not have a cleanup workflow because they were designed for the task, not for the credential lifecycle that task requires.
What the inventory actually looks like
We audited seven production agentic systems before launching Alter. The pattern was consistent. In the most extreme case, a team running AI agents for internal process automation had 1,200 active OAuth tokens across their GitHub organization. They had 12 active agents. The remaining tokens belonged to agents that had been decommissioned, experiments that never went to production, and one-off scripts that ran twice and were abandoned.
None of the zombie tokens had been revoked. All of them were still valid. The average scope was repo:write — full write access to any repository in the organization. The team discovered this when they ran their first GitHub authorization audit, not because anything had gone wrong. Yet.
The median zombie token age across all seven audits was 94 days. Most teams had no idea what scopes their active agent tokens carried, much less the inactive ones. When we asked how they would revoke all tokens associated with a specific agent if they needed to, the most common answer was "we'd have to grep the code."
Why agent token sprawl is different from human token sprawl
Human OAuth token sprawl exists too — people authorize third-party apps and forget about them. Google's connected apps page is the graveyard. But human OAuth abuse has a natural damper: humans are rate-limited by attention. A compromised human account using OAuth tokens generates anomalous behavior — wrong time zones, unusual access patterns — that monitoring tools can catch.
Agent token sprawl has no equivalent damper. An AI agent's legitimate access pattern looks like an attack: high volume, off-hours, systematic coverage of API endpoints. If a zombie token is being used maliciously, the only way to distinguish it from legitimate agent activity is to know which tokens belong to active agents and which do not. Without an inventory, you cannot make that distinction.
The second difference is scope. Humans typically authorize apps for specific purposes — "this app needs my calendar." Agents are often given broad scopes during development because the developer isn't sure exactly which endpoints the agent will need. Those broad scopes persist into production and never get narrowed. An agent that only ever reads PR descriptions ends up carrying a token with full repo write because that's what was easiest to set up in week one.
The three categories of sprawl
Zombie tokens. Tokens belonging to agents that no longer run. The agent was deprovisioned, the experiment ended, or the code was rewritten — but the token was never revoked. These are the highest risk because they represent access that nobody knows exists.
Overscoped tokens. Tokens where the granted scope is broader than what the agent actually uses. The agent asked for write and only uses read. The gap between granted and used scope is latent risk — if the token is compromised, the attacker gets the granted scope, not the used scope.
Shared tokens. One token used by multiple agents or multiple instances of the same agent. This is common in early deployments where the team treats the agent's OAuth token like an API key that gets shared across environments. You lose per-agent attribution entirely, which means your audit log is useless for attribution after an incident.
How sprawl turns into breach surface
The mechanism is straightforward. An agent's environment or secrets store is compromised — misconfigured S3 bucket, leaked .env file, exposed Kubernetes secret. The attacker finds the OAuth token. They know it is valid because nobody has revoked it. They can immediately impersonate the agent with the full scope the token carries.
Because the token's behavior is indistinguishable from the agent's legitimate behavior, the intrusion may not generate alerts. The attacker can stay inside the blast radius of that token for as long as it remains valid — which, without a rotation policy, is indefinitely.
The July 2023 Microsoft breach involved a stolen MSA signing key that allowed attackers to forge authentication tokens for Exchange Online. The breach was not discovered for 25 days. The mechanism — long-lived, high-privilege credentials with no rotation and no inventory — is structurally identical to the OAuth token sprawl problem in AI agent deployments. The scale is different. The architecture is the same.
Fixing the inventory first
Before you can implement rotation or scope enforcement, you need to know what exists. For GitHub, you can enumerate all OAuth apps authorized to your organization via the GitHub API's /orgs/{org}/installations and /users/{username}/authorizations endpoints. For Google Workspace, the Admin SDK's tokens.list endpoint returns all third-party app tokens. Slack provides a similar listing via its App Management interface.
Build a one-time inventory first. Map every token to the agent that created it. Check whether that agent is still running. Revoke anything you cannot attribute to a running agent. This is painful the first time — typically a few hours of manual work — but it gives you a clean baseline to build on.
Preventing sprawl going forward
The core rule: tokens should have a lifecycle that is coupled to the agent's lifecycle. When the agent stops, the token should stop. When the agent is deprovisioned, the token should be revoked. This sounds obvious. Implementing it across every OAuth provider your agents use is not.
There are two approaches. The first is per-provider management: build revocation into your agent deprovisioning workflow, using each provider's API to revoke the relevant tokens. This works but does not scale — each new provider integration adds a new revocation path to maintain.
The second approach is to proxy all OAuth credential requests through a single layer that owns the token lifecycle. When the agent deregisters from the proxy, all tokens it ever minted are revoked automatically. One revocation call, every provider. This is the architecture Alter uses — and the reason it exists.
The security debt framing
Token sprawl is security debt in the strict sense: it is a known risk that you are deferring rather than eliminating. Unlike code debt, security debt has a probability of suddenly becoming very expensive. The longer the zombie tokens exist, the more chances there are for them to be discovered and used.
The teams we work with who took sprawl seriously reduced their active token inventory by 60-80% in the first cleanup. What remains is attributable, scoped appropriately, and on a rotation schedule. That is a fundamentally different risk posture from the default — and it took about a day of work to get there.