Governed execution for AI agents
Let AI agents act. Without letting them loose.
TrustRail sits between your AI agents and the real world. It checks every consequential action against your rules, asks a human when it matters, and keeps your credentials out of the agent’s hands — with a tamper-evident record of everything.
Why you need this
AI agents are genuinely useful right up until one buys the wrong thing, emails the wrong person, or deletes something that mattered. TrustRail exists for that moment.
Agents act faster than you can watch
An agent can send a hundred emails or place an order in the time it takes to glance at a screen. Hoping it behaves is not a plan.
One place to say yes, no, or ask me
You set simple rules once. TrustRail applies them to every action, every time — and anything risky waits for a tap from you before it happens.
Proof of everything, after the fact
Every decision is recorded in a log that cannot be quietly edited. When someone asks “what did the agent actually do?”, you have the receipt.
How it works
Think of it as a seatbelt for your AI agents: they keep driving, and TrustRail decides what actually happens when they reach for the real world.
Bring your agents over. Keep the guarantees.
Everything below ships in the product today. Connect once, decide deterministically, and contain from one console when something goes wrong.
Setup assistant
Moving an agent in takes one pass
The desktop app scans this machine the way Migration Assistant scans an old Mac: it finds your MCP servers, agent configs and provider keys, shows you exactly what it found, and imports only what you tick.
It runs as part of the desktop app — no Docker, command line, or local stack is required to discover and prepare your existing agent setup.
It only offers providers this build can actually govern — the list comes from the action registry, not from a table that can drift. Credential values never leave the app; you enter the key in the console, where it is tested against the real provider and handed straight to the gateway.
Connection wizard
A credential is proven before it is stored
Every connection is tested with a real read-only call to the provider over the same pinned-origin transport the gateway uses. You get back one of three words — valid, invalid, unavailable — and never the provider’s response.
Connect stays locked until the current credential, origin, provider and environment have all produced a valid result. Change any one of them and the proof is void.
Incident runbook
Containment is a button, not a paragraph
Acknowledge, contain, revoke credentials, inspect the evidence, and recover — each one an executable control in the console, each one gated by the permission it actually needs and each one appended to the tamper-evident chain.
A freeze does not burn credentials, because the next rung has to have somewhere to escalate to. The console says which rung you are on and what it did.
The action lifecycle, governed end to end
An agent never holds provider credentials and never calls a provider directly. Every consequential action flows through five governed stages, each producing verifiable evidence.
Built for the failure cases
Most agent frameworks optimize the happy path. TrustRail is engineered around what goes wrong: prompt injection, replayed requests, stale authority, crashed processes, and ambiguous provider timeouts.
A denied action cannot execute
The gateway consumes a signed, digest-bound, one-use token before any provider call. No token, no execution — enforced in a separate process with its own least-privilege database role.
Mutation invalidates authorization
Approvals bind to the canonical digest of the exact request. Change one byte of the payload and every downstream authorization fails closed.
Delegation only narrows
Agent-to-subagent handoffs are signed grants checked on ten axes — capabilities, resources, spend, depth, time — in both the application and the database. Revoking an ancestor kills the whole subtree.
Ambiguity is never a retry
A provider timeout is recorded as UNKNOWN and reconciled by a stable idempotency key. The guarantee is at most one logical operation — stated honestly, engineered thoroughly.
Tenants are isolated in the database
Forced PostgreSQL row-level security with composite tenant keys means isolation holds even if application code has a bug. Cross-tenant probes return 404, never a hint.
Evidence is tamper-evident
Every privileged transition appends to a per-tenant SHA-256 hash chain in the same transaction. The whole chain is re-verifiable through the API on demand.
Honest enforcement modes
TrustRail tells you exactly what each mode guarantees — and what it does not. Only Enforce mode prevents external action; the others are for visibility and rollout.
| Mode | Behavior | Security claim |
|---|---|---|
Observe | Receives telemetry alongside or after actions | Visibility only — no prevention claim |
Shadow | Evaluates before the action; the client still executes independently | Policy impact measurement — no enforcement claim |
Decision | Returns allow/deny/approval, but a client could bypass it | Advisory authorization |
Enforce | The gateway holds the provider credential and the execution path | Protected against ordinary client bypass within the deployment boundary |
Two integration modes, two different promises
Start by gating the tools you already have. Move the ones that matter inside the boundary. The difference is not convenience — it is what survives a compromised agent process, and TrustRail will not let you confuse the two.
guard() — one wrapper, no migration
Your tool keeps its signature and its implementation. TrustRail decides whether it runs, and a denial reaches the model as a tool result that tells it not to route around the refusal. Works with every action type in the registry.
Gates your code; does not hold your credentials. A compromised agent process could bypass it. Not enforcement.
act() — the agent never holds the credential
Drop the local implementation. A separate gateway process holds the provider credential, revalidates every fact, and spends a one-use Ed25519 authorization. The agent cannot perform the action on its own.
Requires a reviewed provider adapter, so it covers the action types the registry marks EXECUTABLE.
// Enforce mode: evaluate, wait for a human if required, execute const result = await agent.act({ purpose: "Reorder the stock the planner flagged", actionType: "payments.purchase.create", resource: { type: "payment", id: "order-4821" }, parameters: restockOrder, financial: { amountMinor: "4999", currency: "USD" }, waitForApprovalSeconds: 120, }); // -> result.status: "EXECUTED" | "DENIED" | "AWAITING_APPROVAL"
A denial is a returned result, never a thrown error. Refusing an action is a normal answer, and code that treats it as a crash ends up working around it.
Drops into the frameworks you already use
The adapters are matched structurally and import nothing, so there are no peer dependencies and no version coupling. Governance refusals become tool results rather than exceptions that abort a run.
| Framework | Integration |
|---|---|
| Vercel AI SDK | governedAiTool(agent, spec, tool) |
| LangChain / LangGraph | governedLangChainTool(...) · Python @agent.guard(...) |
| OpenAI / Anthropic tool loops | governedHandler(agent, spec, handler) |
| MCP-capable agents | One config entry — Claude Code, Claude Desktop, and others |
| Anything else | governedExecute · governedTextExecute |