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.