Free for developers, now and always.The whole enforcement layer, self-hosted. No card.

pip install trustbandStart in shadow mode

[ Trojan Prompt Defense ]

Stop trojan
prompts at the gate.

Instructions your agent reads, hiding in content it trusts: a file, a page, a tool result. It can't tell an order it was given from one it found. trust.band records where every argument came from, so a trojan prompt gets read, and doesn't get to act.

Same command. Different origin. · byte-identical command · two originsclaude code · bash
SESSIONyou typed it
git push --force origin main
ALLOWtrust.band
ALLOWparams-only
TOOLlifted from a file the agent read
git push --force origin main
DENYtrust.band
ALLOWparams-only
An engine reading only the call's parameters cannot separate these — the parameters are identical. Reproduced against a competitor's live evaluator, August 2026.

Included free — the ones you open every day

  • traceevery argument, with the band it arrived at
  • shadow-reportwhat it would have refused, on your own traffic
  • infera policy that permits exactly what you already do
  • replaya policy change against recorded traffic, before it ships
  • reporttokens by class, read from the transcript, never estimated
  • exportthe whole record to any OTLP collector, no SDK
  • packsseven starters, each with the number it was measured at
  • testunit-test a policy in milliseconds, in CI
  • revoke-agentrefuse every later call by a named agent, from any process
  • lockpin tool descriptions, servers and skills; refuse the rug pull
  • alertsa webhook per event class to Slack, Discord, ntfy — yours, free

Sixty seconds,
start to first refusal

0.082 msDecision latency, p50, inside your own process. No network call that can time out.

An injected instruction doesn't break in. It persuades an agent that already holds permission to use it differently.

How the bands work

Injection is a privilege problem, not a content problem

01 / THE PROBLEM

Every argument still looks legitimate, because every argument is legitimate. It just entered from the wrong place.

Filtering dangerous instructions out of content is a losing game: the space of phrasings is unbounded and one miss is enough. Inspecting a call's parameters is a better game but a partial one, because an attacker's account number and a real one are both just account numbers.

The question left is where a value came from. trust.band answers it at the boundary, before the model has a chance to be persuasive about it.

The stamp is applied on arrival and the value's own claim about its origin is never read — so nothing inside the conversation can raise its own trust level.

Where provenance matters, and where it doesn't

02 / THE RESULT

Every figure sits beside its undefended baseline, because a defended number on its own describes the model, not the defence. Predictions were registered and committed before each run.

SuiteWhat an argument isUndefendedParams-onlytrust.band
AgentDojo bankingEnumerable — payees, amounts36 / 1440 / 1440 / 144
AgentDojo SlackFree text46 / 10546 / 10522 / 105
AgentDojo Slack, second attackFree text40 / 10537 / 1059 / 105
Attacks succeeding; lower is better. AgentDojo v1.2.1, three attack phrasings, on a model susceptible to them — the gate reads parameters and provenance, so it does not depend on which. On banking an allowlist of payees does the entire job and we have no advantage — that row is published because it is what makes the Slack rows worth reading. Full record, including every failed prediction

Four bands, one lattice

03 / THE MODEL
GOVERNANCE

The policy and the keys behind it. Nothing an agent can reach or influence.

SESSION

What the operator typed or approved in this session.

TOOL

Anything a tool returned — file contents, search results, API responses, another agent's output.

USER

Untrusted third-party content reaching the agent by any other route.

Combine two values and the result takes the lower band. Trust never rises through a derivation — the property the enforcement model is checked against, and the one an injected instruction needs and cannot obtain.

A policy reads like a rule

Constrain an argument by band, by value, or by both. Mark a rule confirmable and a refusal becomes a question rather than a wall.

# a transfer recipient must be typed, not read
grant: banking.transfer
  recipient:
    min_band: session
    in: known_payees
  amount:
    max: 5000
  confirmable: true

A log you can hand over

Allowed or refused, each entry names the rule that decided, the band of each argument, and the outcome, including when the tool itself raised an exception. Hash-chained, so a missing or altered entry is detectable.

A refusal tells the operator which rule refused and why, rendered from the recorded provenance rather than from anything the model wrote. That message is the part of this product worth having.

In a swarm the record names the agent, not a session: researcher · send_message. The name is bound under the same key that mints capabilities, so a forged or borrowed one is refused before any rule is read, and revoking an agent kills every capability it held without touching another. Local identity, shared across processes by a key file; it attributes, it does not isolate code running in the same interpreter.

Audit format

Fix the plan before the agent reads anything

State what a task may do and where it may send things, before its first read. An action outside that plan is refused, whatever the page said. Plan-then-execute is a known pattern; anyone can assert one.

Almost nobody can check it. A plan written after the agent has read a poisoned page may be the injection — and a plan the attacker wrote is worse than none, because it looks like a control. Checking that requires knowing whether tool output had already entered the session, which is what provenance records and a parameter rule cannot see. A plan fixed too late is marked untrusted here, and every check against it refuses.

Measured in a live agent loop. An injected page instructing the agent to copy its output to an unplanned address:

# no plan — the injection lands
reached the attacker 10 / 10

# with a plan — same page, same model
reached the attacker 0 / 10
benign task still completed 10 / 10
Both arms matter. A defence that refuses an attack nobody mounted proves nothing, so the undefended run is published beside the defended one. The plan cost zero benign completions. Not yet measured: whether an agent recovers from a refusal that arrives mid-task — in every run above, the refusal came after the useful work was done.

It starts by refusing nothing

04 / ADOPTION

Install it and it watches. Every decision it would have made is recorded and surfaced; nothing is blocked. Run your normal work for a week, read the report, then enable the rules you actually want.

A tool that enforces from the first call has to be right immediately or it breaks your agent — the objection that gets security tools uninstalled. Shadow mode is the default here, not a flag.

Adapters today: Claude Code, MCP, LangChain, LangGraph and CrewAI for tool calls; LangChain and LiteLLM for model constraints, where the gate's hint drops the deployments a step may not reach and the router chooses among the rest. GitHub Actions next. Every adapter passes one conformance suite, so they cannot drift into separate products. Each of the three framework adapters was written against the installed library rather than its documentation, which is how two silent bypasses turned up — in one, the framework called a different method than the one being guarded, so the tool ran while the checks looked green.

Which leaves a problem worth naming: a week of zero refusals shows you nothing. So the record is readable on its own. trace replays a session showing the band each argument arrived at — on 600 real events, 0 refusals and 71 arguments that came from tool outputrather than from the operator. That is the number that justifies keeping it installed on a day nobody is attacking.

replay tests a candidate policy against recorded traffic, and refuses to answer when the record cannot support the replay rather than reporting fewer refusals than the truth. report accounts for tokens by class, never estimated. export ships the whole record to any OTLP collector with no SDK and no dependencies.

# no dependencies
pip install trustband

# starter policy + hook config, shadow by default
trustband init

# ...a week of normal work...

trustband shadow-report
400 calls observed, 0 would have been refused (0%)
SHADOW — nothing was blocked. This is measurement, not protection.

# a policy permitting exactly what you did
trustband infer
400 permitted call(s) -> 5 grant(s)
written to inferred.policy.json

Zero is the expected result on legitimate work, and it is the point: across 1,119 real tool calls from an actual session the gate refused 0.7%, all of them tools simply missing from the starter policy, at 0.090 ms per decision.

How we compare

05 / THE LANE

APort is the closest product to this one and worth your time — more integrations, a shipped identity spec, further along. The row that separates us is the third.

Capabilitytrust.bandAPortFramework guardrailsClassifiers
Pre-action authorizationYesYesPartialNo
Value and parameter policiesYesYesPartialNo
Argument provenance in the decisionYesNoNoNo
Shadow mode before enforcingDefaultNoNoVaries
Decision runs in your processYesHostedYesVaries
Machine-checked enforcement modelVerus, depositedNoNoNo
Tamper-evident auditHash-chainedEd25519 signedNoNo
Instant revocationKey rotationStatus lookupNoNo
Agent identity specLocal, MAC-boundOpen Agent PassportNoNo
Tool-definition pinningLockfile, MAC-boundNoNoNo
Framework integrations59+NativeVaries
Deliverable / quality gatesYesYesNoNo
Open sourceApache 2.0YesVariesVaries
Assessed against published documentation in September 2026, and for the provenance row against a live policy evaluator in August 2026. If anything here is out of date, write to us and we will correct it.

Free to protect your own agents

06 / TERMS

The whole enforcement layer is free forever, self-hosted, no account and no card. Provenance is deliberately in the free tier: if you cannot experience the thing that makes this different, the free tier is only a worse version of someone else's.

Free

agents you run for yourself

£0 forever
  • Gate, provenance, plan-then-execute, contracts
  • Shadow mode, inference, trace, replay, export
  • Claude Code, MCP, LangChain, LangGraph, CrewAI
  • Named agents, the lockfile, free alerts
  • Model constraints: which models a step may reach, by band; cost ceilings refused at the gate
  • Unlimited agents, calls, people
  • Self-hosted, your own key
Install it

Pro

agents you run for paying customers

£500 / month
  • Everything in Free
  • Retained audit, verified on ingest by a party who cannot edit it; search across devices
  • One signed policy everywhere, verified on each device
  • Regression: what a policy change would have refused last week
  • Per-client caps and an invoiceable report
  • Approvals routed to a colleague or client
Start Pro

Enterprise

separation your auditor has to see

£2,500 / month, from
  • Everything in Pro
  • Bring your own key, your own KMS
  • Per-tenant cryptographic separation
  • SSO and compliance mapping
  • Proof artifacts as procurement evidence
  • Support with response terms
Book a call

Where the line is. Everything that runs on your machine is free: the gate, the ledger, replay, contracts, the lockfile, agent identity, local alerts. Nothing of ours runs, nothing leaves your box, and it stays free.

You pay when someone else is involved. Running agents for a client or a team means the record has to live somewhere the laptop can't lose it, the policy has to reach every machine, and someone else has to be able to sign in. That takes a service of ours running, and external ones with it: hosting, email, payment. Pro is that service. Free protects you; Pro proves it to someone else.

Work alone, but need something of ours running while you are away? That is an add-on, not a tier: Unattended, £14.99 a month, sends a refusal a person may answer to your phone and waits for the answer.

After you pay: your key appears on the next page, once. trustband login with it on any machine, then trustband sync. Sign in any time at trust.band/account to rotate the key, add colleagues, or manage billing. If a subscription lapses, enforcement and the local log carry on unchanged and only the hosted parts stop.

Stated here rather than discovered later

07 / WHAT THIS DOES NOT DO

Where a policy can list every allowed value, provenance adds nothing

On the banking suite an allowlist of payees reaches zero attacks without us. Provenance earns its place when values are free text and there is no list to write.

Paraphrasing escapes

A payload surviving into an argument verbatim is caught. One the model restated in its own words is not, and that is the residue in the Slack figures. Token matching closes part of the gap and is off by default, because it flagged 4.9% of ordinary commands on real traffic.

Frontier models refuse most of these attacks unaided

A current frontier model contained 72 of 72 AgentDojo attacks with nothing installed. On such models the value here is the audit trail and the absence of any benign-task cost, not interception. Every attack figure above comes from a susceptible model.

A pin does not say the first version was clean

Tool descriptions, server entries and skill files are pinned when you accept them and refused when they change, and the pin is bound into every capability's MAC. That catches clean-then-dirty, which is the attack. It says nothing about whether version one was clean; scanning does that. Run mcp-scan in CI and trust.band at the gate.

A model pin sees a version only when the response names one

Model constraints decide, per step, which models the bands in context may reach and how much a session may spend, and refuse at the gate rather than on the invoice. A provider's silent swap behind an unchanged name is invisible by construction; drift is seen when a response names a version, and refuses the next call, not the one that revealed it. Where the framework lets a callback refuse, LangChain and LiteLLM today, the gate stands in front of the call; Claude Code and MCP see no model call. Any saving is arithmetic on your own price table until your traffic says otherwise.

The model is proved; the implementation follows it

31 obligations discharged in Verus against the enforcement model, and 17 counterexamples correctly rejected. There is no extraction and no refinement relation — the Python implementation is held to the model by a conformance suite, not by a proof.

Five design partners

Chosen for running agents against things that matter. Direct access to the person who built it, policy work done with you, not handed over, pricing fixed at what you sign, and real influence over what gets built next. In return we want your shadow reports and your objections.

Apply
Partners

One surface of four

08 / WHERE IT SITS
isovertCryptographic tenant isolation for confidential AI serving. isovert.com
NablaDBConfidential multi-tenant vector retrieval. nabladb.com
DeletablePer-subject cryptographic erasure for Article 17. deletable.org
trust.bandProvenance-aware authorization for agents, on the warrantable core.