The Ratchet Effect: Why AI Agent Permissions Only Go Up
6 min read Fullmakt Team
- governance
- credentials
- agents
- data-ownership
- traceability
- agentic-actions
Ask an engineering team what their support-triage agent can access today, and you’ll usually get an answer for what it was built to access — read the ticket queue, draft a reply. Ask what it can actually reach right now, after eight months of “just add this scope so the demo works” and “give it write access temporarily while we test the escalation flow,” and the honest answer requires someone to go read the actual grants. Almost every time, the real list is longer than the one in anyone’s head. Access only went one direction.
Grants are a five-minute Slack message; revokes never happen
The mechanics explain why. Adding a scope to an agent’s credential is fast, low-friction, and reversible-feeling: someone hits a blocker, a teammate adds the permission, the task unblocks, everyone moves on. Removing a scope is none of those things. It requires proving a negative — that nothing still depends on it — and the person who’d have to make that call has no easy way to check. So the default becomes “leave it, it’s not hurting anything,” which is true right up until it isn’t.
This is the same ratchet familiar from human identity and access management, except it’s worse for agents for three reasons specific to how they get built:
- Agents ask for access far more often than humans do. A human requests a new permission when their job changes. An agent’s task list can change weekly, and every new task tends to arrive with its own “just grant it” request rather than a review of what the agent already holds.
- Nobody runs an annual access review on an agent. Human accounts get swept up in periodic recertification because compliance frameworks demand it. Agent credentials, especially ones stood up outside a formal IAM process, often aren’t even on the list of things anyone recertifies.
- The person granting access is rarely the person who’ll notice the cost. The engineer adding a scope to unblock today’s task isn’t the one who’ll be answering “why could this agent touch billing records” during an incident review six months later.
Why this is a data-ownership problem, not just tidiness
Permission creep sounds like housekeeping until you trace what it actually means for who owns which data an agent can touch. An agent that started with read-only access to a support ticket queue, then picked up write access to the CRM to auto-update ticket status, then picked up access to the billing system because one task needed to check a customer’s plan tier, is now a single credential with reach across three data domains that were never supposed to be reachable from the same login. Nobody designed that footprint. It accreted, one unblock at a time, and the credential that resulted has more standing access than the scoped credential model was supposed to prevent in the first place.
The failure mode isn’t hypothetical. When that agent is compromised by a prompt injection, or simply misreads an instruction and acts on it, the blast radius isn’t “whatever it was built to do” — it’s everything the accumulated grant list allows, including scopes nobody remembers approving and few people would approve today if asked cold. Agent offboarding solves the end-of-life version of this — revoking access once an agent is retired — but creep is the mid-life version: the agent is still in daily use, still doing useful work, and still quietly holding more than it needs at every point in between.
The business case: credentials that can’t accumulate what they were never granted for the current task
Static API keys and long-lived service-account tokens are the substrate that lets creep happen, because every scope ever added to one stays added until someone actively goes looking for it. Fullmakt’s approach removes the mechanism rather than relying on discipline to counter it:
- Every credential is scoped and short-lived, minted per call against the policy in force right now — not a standing grant that outlives the task it was issued for. There’s no long-lived key sitting in a vault accumulating scopes across months of ad hoc requests.
- Policy, not a credential’s history, decides what’s allowed. Because access is computed at request time from the current policy document instead of read off whatever was bolted onto an old token, a scope that’s no longer justified simply isn’t granted on the next call — no revocation project required.
- Every dispensed credential is logged against the call it served, so answering “does this agent still need billing access” is a query against actual recent usage instead of a guess based on who might still depend on it.
- Widening access still goes through the same policy and, where configured, human approval gate every other grant does — so “just add the scope to unblock today” is a decision made visibly, with a record, rather than an untracked edit to a key’s permissions.
The result isn’t that agents get less access when they genuinely need it — it’s that access stops being a one-way ratchet. What an agent can do today reflects what today’s policy actually authorizes, not the sum of every exception anyone has ever granted it.
FAQ
Isn’t this the same problem as agent offboarding? No. Offboarding is about revoking access when an agent is retired entirely. Permission creep happens to agents that are still actively, usefully running — the risk is that a live agent quietly holds more standing access than its current tasks justify, not that a dead one was never cleaned up.
Can’t we just run periodic access reviews on agent credentials, like we do for humans? You can, and it helps, but it’s a snapshot audit of a problem that’s continuously being created. A quarterly review catches creep that accumulated over the quarter; it doesn’t stop the next ad hoc grant from starting the clock again the day after the review closes.
Doesn’t scoping a credential once, at creation, solve this? Only until the first “just add this scope” request. A credential scoped correctly on day one and then hand-edited eleven times over the following year ends up exactly where an unscoped one would — the difference is only how it got there.
How does a broker know what scope is still justified? It doesn’t guess — it evaluates the current policy against the specific call being made. If policy hasn’t been updated to authorize a scope for present use, that scope isn’t issued on the next credential, regardless of what a credential minted months ago used to carry.
Does this apply to A2A and MCP tool access too, or just API credentials? The same ratchet applies anywhere an agent accumulates standing permission — an A2A skill grant or an MCP tool binding creeps exactly the way a REST scope does, for the same reason: adding is easy, and nobody wants to be the one who removes something that might still be load-bearing.
The uncomfortable test for any team running agents in production: pull the actual grant list for your longest-running agent and read it against what it does today, not what it was built to do. If the answer is “we’re not sure why it has that,” the ratchet has already turned further than anyone noticed — and the fix isn’t a bigger spreadsheet, it’s a system where access has to be re-earned on every call instead of accumulated once and forgotten.