An agent gets approved once. Then it keeps acting.
ABERNATE is a release gate for automated work. It checks each action as it happens, rather than once at the start. Actions outside its authority do not run, and what runs leaves a signed receipt an auditor can verify on their own.
82.9%of organizations report that security or compliance reviews have delayed AI projects from moving into production
80%+report deploying AI agents in a diminished state at least occasionally because of security concerns
Both figures are EMA's, from their April 2026 survey of 152 IT and security leaders, quoted from EMA's own published summary. Not our numbers and not about this product. Two further figures were removed from this page: they came from trade-press summaries and could not be confirmed against the publishers.
Approval happens once. The work happens all day.
Security review does real work. It decides which AI tools are allowed, which vendors clear procurement, and what data those tools can see. All of that is about what the agent is.
The gap that follows is not our observation. Four independent groups have described the same missing layer in 2026 alone, under four different names, and at least one has argued the whole category is aimed at the wrong place. Sources in the technical packet.
Then the agent runs. It calls an API, writes to a database, triggers a workflow, holds a document. Nothing sits between that call and the consequence, and more than half of agents in production run with no oversight or logging at all. A third of organisations say they could not immediately stop a rogue agent.
A reviewer has two options: hold the project, or let it through with the agent restricted. More than 80% of organizations report doing the second at least sometimes, and end up running a smaller version of what they paid for.
ABERNATE covers the part nobody checks: what the agent is allowed to do, at the moment it does it.
WHAT THE CUSTOMER'S COUNSEL GETS HANDED. VERBATIM.
{
"mission_id": "legal-hold-sweep-4471",
"purpose": "Sweep a custodian folder under legal hold: catalogue
every file, hash each one for chain of custody, look
inside archives, and flag material appearing across
more than one source. No network access.",
"operational_status": "PASS",
"steps_executed": 4,
"receipt_chain": "VALID",
"release_required": true,
"released": false,
"squad_leader": "BLOCKED: no clearance recorded for
legal-hold-sweep-4471. Run the go/no-go
board and record a GO before release.",
"final_receipt_hash": "fc1244d6c1c8ff789c951f8be42b2627...",
"metrics": { "completion": 1.0, "success": 1.0,
"authority_coverage": 1.0, "receipt_integrity": 1.0 }
}
PASSThe job worked. Four steps ran, none errored.
VALIDEach step wrote a signed record, and they still agree with each other.
1.0 ACROSS THE BOARDNothing partial. Every action covered by a stated authority.
released: falseIt shipped nothing. squad_leader is the named human who has to clear a release, and none had.
Output from the sample that ships with the package. Every step ran, every check passed, and it shipped nothing, because no human had cleared it. Success is not permission, and being able to show the difference is what the review is asking for.
Agents ship late, or ship restricted.
An agent that clears review with its autonomy cut is not a win, it is the budget spent and the capability withheld. An agent still in review at month six is the same money with nothing to show at all.
Both happen for one reason: the reviewer has no control to point at, so the only levers left are delay and restrict. Give them a gate that refuses on the action itself, and a signed record of every refusal and every clearance, and the conversation changes from how much to take away to what evidence gets produced.
Regulatory exposure, audit cost and liability allocation all follow from this and none are ours to quantify. They are the buyer's arithmetic, not our claim.
No customer has measured a dollar of any of this, so no dollar figure appears on this page.
hello@abernate.com · the technical packet, on request
The four checks
Permission is not one setting. Before an action runs, four separate questions have to answer yes.
01Can this worker do this at all? Its contract lists the actions it has and the paths it may read.
02Does the command being run permit it? A command is a narrower grant than the worker's full capability.
03Does standing policy allow it? Risk class, network access, evidence thresholds, step limits.
04Did this job actually ask for it? An action nobody requested is refused even when all three above allow it.
ALL FOUR, OR NOTHING · five strong properties and one dead one is a refusal, and the dead one gets named. Nothing averages out.
A named human has the last word and can only say no. Their GO cannot push an action through a check that already failed, and a policy written without that gate is rejected the moment it loads, so no engineer disables it by forgetting it.
That clearance is signed, and checked against a key named in the policy. Until version 9.6 it was not: the deciding human was a line of text in a file, so the gate established that a decision existed and nothing about who made it. Changing the name, or raising a NO-GO to a GO after the fact, now breaks the signature and blocks the release. A clearance signed by a key the policy does not name is refused even though its signature verifies.
Every step writes a receipt, hash-linked to the one before it and signed. A step can cover many files, so this is a record per step, not per file touched. Before the receipt is written, the engine goes back to the target and checks the work against it without asking the worker that reported it — re-counting the files, re-reading them and recomputing the hashes. A report that does not match the target stops the step. Until version 9.6 a receipt recorded what the worker said happened, and nothing checked it. That file goes to the customer's lawyer, the SOC 2 auditor or opposing counsel. Each checks it with a command that ships in the package, against a verification key they were given separately. They still have to trust where that key and that package came from. What they do not have to accept is the operator's word that the ledger is unaltered.
What makes it different
- One bad check stops the action
Scoring systems let a strong result cover a bad one. Here a single failed condition stops the action and the output names which one. There is no total high enough to pass a refusal.
- The attacks that beat it are in the box
Ten forgeries were run against its evidence chain and all ten are caught. One of them was disclosed for months as structurally unfixable, and is now closed. Each is a passing test, so none can be quietly dropped. They are ten attacks this team thought of; an attack nobody here thought of is not in that number. The list, the method, and the record of which ones got through first, ship with the packet.
- Every claim here has been attacked, including by us
Some of the strongest tests in here exist because earlier versions failed them. Those failures remain in the record: the human gate was wrong once, tail truncation survived once, a full-chain reforge exposed a structural weakness, and closing it with signatures opened a new attack that key pinning then closed. Each is now a passing test, so none can be quietly dropped.
Check it without talking to anyone
The figures below came from one run against a public corpus that anyone can download. Not a demo folder, not a benchmark we built.
INThe CPython 3.12.0 source release, straight off GitHub.
sha256 ddfaf383c97f393a7768943630ea01e6c3cfb9af4fbc02655a37a2f3680013d6
014,579 files catalogued and hashed. 100,613,159 bytes. Twelve receipts picked at random and re-hashed off disk: twelve of twelve match what the receipt says.
028 archives opened, 19 entries read. 3,014 patterns traced across more than one source.
03Two independent runs, identical final hash — and the same hash from a different directory. Until version 9.7 that second part was false: receipts embedded absolute paths, so the one number that proves two runs produced the same evidence could not be compared across machines, and the package said so in capitals. Paths are now written against declared roots. The check ships: it runs the same corpus from two directories and compares.
04Ten forgeries against the resulting 4.7 MB signed ledger. All ten caught. Those attack the record. A second set attacks the gate itself. Three of those six were not caught when they were written; two have since been closed and one still is not — it is named, with what it would take to close it. That set ships too, and it is the first thing worth running.
AND IT DID NOT SHIP · every check passed and released stayed false, because no human recorded a decision
The check ships in the package. reproduce.py downloads that tarball, verifies the sha256, grants the corpus through a contract it prints and then revokes, runs the sweep, and compares the five figures above against what it measured. Exit 0 means those five held on that machine. It takes about nine seconds. Three more scripts ship beside it: one runs the attacks on the gate and prints the three it does not stop, one measures the document formats and lists what it declined to open, one rebuilds the hundred-thousand-file corpus and sweeps it. None of them need an account, a key or a call with us.
One more thing happened on the way in, and it was not staged. The first attempt was refused before a single file was read: read path outside authority. No worker contract declared that corpus, so nothing touched it until one did. That is the gate working on data it had never seen.
What it will not do
- It cannot stop whoever holds the signing key
Receipts are signed, so the customer, the auditor and opposing counsel cannot forge one. The security team holding the signing key still can. That is what a signature means, and it turns "could this have been faked" into "who held the key on 14 March", which access records already answer.
- It does not prove the decision was right
It records which authority permitted the action, under what capability, and who cleared it. That record is checkable. Whether the action was the right one is not in it. Whether holding that document was legally correct is a judgement a lawyer makes, and no machine on this page makes it. Anyone who tells a court otherwise will be taken apart on it.
- It has been run on a hundred thousand files, not millions
The largest measured run covers 97,575 files and 1.06 GB, in 58 seconds, from a pinned public corpus the package rebuilds and re-verifies. That is twenty-one times the earlier figure and still two orders of magnitude short of a large archive, and the reason it stops there is in the package: peak memory was 705 MB, because the engine holds the whole file list in memory rather than streaming it. Memory grows with the corpus. Reaching ten million files means changing that design, not buying a bigger machine. A second run of the same sweep on the same container was killed for memory, and that is written down too.
- Three container formats need a dependency it does not have
A sweep over PDFs, Word files, spreadsheets, single messages and a mailbox was measured: every file catalogued and hashed, the chain held, and as of version 9.8 the containers are opened too — the whole zip family, which is what a Word file and a spreadsheet actually are, the whole tar family, and mbox. On that corpus it went from opening 1 container to opening 21. What it still will not open is 7-zip, RAR and PST, because each needs an outside package and this thing has none and runs offline. Those are named in the receipt with the reason rather than quietly missing, and PST is the one a custody buyer is most likely to ask about. It also does not read inside documents — no text pulled out of a PDF, no email body parsed — and never claimed to.
- It only sees work that goes through it
This is the biggest one. ABERNATE rules on actions routed through its own runtime. An agent that calls an API directly, or signs into an application the way a person does, is never checked, is never refused, and leaves no record at all. The package ships an attack that does exactly that and reports it as not caught. Nothing here makes the engine unavoidable; closing that means a proxy the traffic has to cross, or holding the credential the agent authenticates with, and that is a different product with servers in it. What you get is a record of what went through the gate, which is worth what your deployment makes it worth.
- It checks the action, not the thinking behind it
There is a documented argument that this is the wrong layer: that governance has crowded onto execution risk while the real blind spot sits upstream, in how a model framed the options before any action was proposed. That critique is correct about the limit. ABERNATE rules on what an agent is permitted to do. It has nothing to say about why the agent wanted to do it, and a related objection holds that intercepting after reasoning completes is weaker than governing the reasoning itself. Both are worth reading before buying.
- It does not replace whatever builds the agents
It sits underneath whatever framework the agents are built with, and rules on the actions they take.
What it needs to run
192 of 192 tests pass from a cold extraction on Python 3.12. Standard library only. No dependencies, no network, no account, no GPU, nothing to host. The internal file manifest is generated from the folder and refuses when the two disagree, because a hand-typed count is what went wrong twice.
What transfers
Sold outright or licensed. The transfer includes the source, the hashes, the provenance record, the full adversarial test corpus and every defect ever found in it, including the ones still open. Evaluation copies are confidential.
hello@abernate.com