Trust & security

Three parts hold
the boundary.

A door every request must pass, a record of what passed, and a wall on the model data plane. Everything below is what those three parts actually do.

Part 01 · Control

The auth gate

A sidecar process in front of every agent. It owns the public port, refuses everything without a valid credential, and proxies only authenticated traffic inward.

  • Fails closed: no credential, no response, including for paths that do not exist
  • Cloudflare Access SSO, a bearer token, or the per-process launch token
  • An allow-list decides who gets in; a minted cookie carries the decision
  • The agent's own port is never published: agents dial out, nothing listens on their side
  • Inert until you configure a credential, so it cannot lock you out
Shipped Sidecar 0.0.3In every bundle
BrowserSSO or bearer
→
Auth gate401 unless authenticated
→
Agentloopback only
Public surface: one port, one policy, nothing else
Every step logged against the validated principal
Part 02 · Control

The audit chain

Two records, with different jobs. The agent's own journal says who did what, in the order it happened. The audit log is the tamper-evident copy the agent cannot reach.

  • Each action bound to a validated principal, not a client-supplied header
  • Rule hits recorded by rule id and a redacted snippet, never by the secret itself
  • Audit data is not model-visible, so an agent cannot read its own compliance record
  • Exportable to an auditor without exposing credentials or provider keys
  • Who did it, who approved it, who answered it: always answerable

Identity in the record, not beside it

Every durable user/message row carries the acting principal as source.actor, resolved from the auth gate's rpcId → principal binding, captured independently of the agent, so the agent cannot write its own alibi.

Question answers are stamped answeredBy. Approval-gated results are stamped decidedBy with the outcome, and the decider is the person who actually clicked, not the session driver. The enrichment is strictly additive: an unreachable sidecar leaves the message untouched and never aborts a turn.

Shipped Hash-chained JSONLAppend-only
Journal row · shape
typeuser/message
seq8
rpcId70e7…c41b
actormember (validated)
sourcecf
Audit record · shape
actormember (validated)
actionrestart-gateway
targetag-0f31
decisionallowed
matched ruleops.restart
prev hash4d1c…9a2f
secret textnever recorded
Part 03 · Control · In progress

LAW: the wall

An out-of-process context firewall on the model data plane, reviewing what goes out and what comes back, without the user on the other end feeling it.

  • A customised judge, not a general model: a small model tuned to match a much larger one
  • One forward pass, on the same box: no second provider round-trip
  • Rust core, stateless per request: latency stays flat as concurrency climbs
  • No database in front of the decision: audit is written after it, never before the reply
  • Per-agent policy, versioned and hot-reloadable; deterministic checks for credentials and secrets
  • Fails closed: a missed budget refuses the request
In progress Rust · tokioOn-box judgeNo user-visible delay
Agentsany harness
→
LAWpolicy · checks · judge
→
Provideragent's own key
Refusals reach the agent with a reason it can read
Nothing is signalled to the caller in v1 shadow mode

Two things the parts above imply, but do not say.

Sovereignty

Agents run on hardware you own, on-premise or in your VPC, with no cloud control plane in the deployment path and no training on your data. The images we run are the images you get.

From the harness and the deployment model

Least privilege

An agent gets the tools its role needs, runs as non-root, and cannot acquire a capability that is not in the registered bundle. Destructive actions require a person.

From role templates and the bundle registry

Ask us the hard question

Bring your security reviewer. If something here does not hold up, we would rather find out before you deploy.