Concepts6 min read

Deny-by-default permissions for AI agents

Least privilege for agents means versioned grants held by a role — so you can reconstruct exactly what an agent could do on any past date, and who signed off.

An examiner sits across the table and asks a single question: on the third of March, what was this agent allowed to do? Not what it did — what it was permitted to do, and who decided that. If your answer is "let me check the code we shipped that week," you have already lost the room. The agent's permissions were never a record. They were a side effect.

This is the gap between how engineers think about agent permissions and how a regulator thinks about them. To an engineer, the question is "what can this thing call right now?" To a regulator, the question is "what could it call then, who authorized that, and can you prove the answer hasn't been edited since?" The first is a configuration. The second is a grant ledger — a permanent, time-stamped record of every capability an agent ever held and the human who granted it. Most teams have the first and assume it is the second.

Deny-by-default, in plain terms

Deny-by-default means an agent can do nothing until something explicitly permits it. The starting position is zero capability. Every tool it can call, every system it can touch, every action it can take is there because someone opened that specific door — and every other door stays shut.

This is the opposite of how most agents are built. The common pattern is permit-by-default with exceptions: the agent gets broad access to a toolset, and you write instructions telling it what not to do. Don't transfer over $10,000. Don't delete production records. Ask a human before filing. That is a list of polite requests bolted onto an actor that already has the keys.

The principle underneath deny-by-default is least privilege — give an actor the minimum capability it needs to do its job, and nothing more. It is not a new idea. It is the control that governs which bank employee can authorize a wire, which lab analyst can sign a batch record, which clerk can approve a refund. Regulators have demanded it of people for decades. The only thing that changed is that the actor is now a model.

Why a hardcoded tool list is not a grant

Here is the trap. A team adopts deny-by-default — genuinely — and writes a tool list in code: this agent may use these five functions. Access is now scoped. The agent cannot do anything outside the list. So far, correct.

But that list is not a grant. It is a fact about the current deployment. When it changes, the old version is overwritten and gone. There is no record of who added the sixth tool, when, on whose authority, or what the list looked like before. Roll the codebase back to last quarter and the permissions roll back with it — silently, with no trace that they were ever different.

A grant is something else. A grant has four properties a code constant does not:

Property Hardcoded tool list A real grant
Scoped Yes Yes
Versioned No — overwritten on change Yes — every version preserved
Attributed No — who changed it is lost Yes — names the approver
Reconstructable No — only the current state exists Yes — query any past date

The difference matters precisely when an investigation is underway. By the time anyone asks what the agent could do on a given date, the deployment has changed a dozen times. A grant ledger answers the question in seconds. A code history answers it with an afternoon of git blame, a stack of pull requests, and a prayer that nobody force-pushed.

The grant lives on the role, not in the agent

The cleaner way to hold permissions is to separate the actor from its authority. An agent is an identity — a named principal. A role is a bundle of grants. An agent holds exactly one role at a time, and capability flows only through that role. The agent itself owns no permissions; it borrows them by wearing a role.

This separation is what makes the ledger work. When you grant a capability, you are versioning the role, not patching the agent. Swap the model behind the agent, re-prompt it, even replace it entirely — the authority boundary does not move, because the boundary was never inside the thing you swapped. This is the same logic that lets a control plane outlive any single agent: the limits live somewhere the agent cannot edit.

It also makes segregation of duties enforceable. If permissions are smeared through prompts and code, you cannot prove that the agent which prepared a wire was structurally incapable of approving it. If permissions are grants held by roles, you can — because a maker role and a checker role are two distinct, versioned bundles, and one principal cannot hold both on the same run.

What "versioned" buys you under examination

Consider the three rules a regulated buyer already lives under. In pharma, 21 CFR §211.22 makes the quality unit's authority a matter of record — who is permitted to do what, documented and segregated. In banking, the Wolfsberg Group names the four-eye standard as the control for high-risk transactions, which presumes you can show who held which authority. NYDFS Part 504 requires an annual certification that an institution's transaction-monitoring program is sound — including the controls around who can change it.

None of those rules accept "the code reflects current policy" as evidence. They ask for a record that survives change. A versioned grant ledger produces exactly that record as a byproduct of normal operation. Every grant, every revocation, every expansion of scope is written once and never overwritten, each entry naming the person who approved it.

And because the ledger is hash-chained and signed, it is not merely available — it is tamper-evident. You can show an examiner not only what the agent was permitted to do on the third of March, but that the record of those permissions has not been altered since. That combination — deny-by-default grants, versioned on a role, written into an offline-verifiable audit trail — is the whole point. Least privilege you cannot prove is just a configuration you hope is correct.

The test to run

When you evaluate any agent governance approach, ask one question and watch the answer. Reconstruct, for an arbitrary past date, exactly what this agent was allowed to do, and tell me who authorized each capability it held.

If the answer involves checking out an old commit, reading deployment logs, or asking the engineer who remembers, you do not have a grant ledger. You have a tool list with good intentions. And in a regulated industry, intentions are not a record an examiner can verify.


See how it works, or book a demo to watch an agent get blocked from approving its own work — live.

Where this goes to work

How MakerChecker works — the six primitives

Agents as employees, versioned grants, structural segregation of duties, approval gates, role limits, and a signed audit a regulator verifies offline.

See it for yourself

See an agent get stopped.

One command starts the demo: an agent stopped from signing off its own work, and the signed evidence file an inspector can check for themselves.

Designed against the rules your auditors already enforce.