Skip to main content

Reliability

Unveilr sits in front of production agent actions. This page answers, without a meeting, the three things an architecture review asks: how slow are you, what happens when you're down, and how do we get back?

Written to be checkable. Every number below is reproduced by a benchmark in our test suite; every failure behaviour is covered by a test in our suite.


1. Where we sit

agent ──► MCP gateway ──► policy decision (in-process) ──► upstream MCP server

└── registry snapshot, refreshed off the hot path

agent ──► POST /v1/govern/check ──► policy decision ──► allow / deny / scoped_token
(LangChain, CrewAI, function-calling, raw HTTP — no MCP required)

Two properties that make the latency story tractable:

  • The decision is a pure function. No network, no LLM, no external lookup — a deterministic evaluation over the policy set.
  • The gateway's allow/deny path never calls the API. The registry is a snapshot refreshed out of band, so a control-plane hiccup does not sit in the request path.

2. Latency

Measured on the decision engine, warm process, worst case — every policy in the set matches, so all of them are evaluated:

Enabled policiesp50p95p99Budget (CI-enforced)
100.06 ms0.07 ms0.08 ms5 ms
1000.37 ms0.40 ms0.42 ms15 ms
10003.49 ms3.65 ms3.81 ms120 ms

End-to-end POST /v1/govern/check in-process — credential resolution, DB lookups, policy decision and hash-chained evidence sealing, 25 policies:

p50p95p99
full request2.66 ms4.39 ms5.87 ms

Scaling is linear, not quadratic — 10× the policies costs ~9.4× the time, and CI fails if that shape changes. A control plane that is fine at 100 policies and unusable at 1000 cannot be sold to an estate that grows.

Budgets are set roughly an order of magnitude above observed, so the guard catches a regression in the shape of the cost (an accidental O(n²), a regex recompiled per call) without flaking on a busy runner.

Not yet measured, and we say so: sustained throughput under concurrency, and latency from a real client across the network. The numbers above exclude network time and are single-threaded.

3. Failure behaviour

The control plane fails closed everywhere it decides. Each row is enforced by a test, not just intended:

What failsResultWhy
Agent credential cannot be verified (control plane unreachable)deny, and the failure is not cachedAn unverifiable identity is not a trusted one; caching a transport error would extend an outage into a security gap.
Credential unknown, revoked, or expireddenyThe per-agent kill switch must be immediate.
Credential not bound to an approved agent identitydenyThe deployment gate.
Server unknown / not registereddeny (404)You cannot govern what was never declared.
Server not approveddeny (403)Approval is the gate, not a label.
Tool not in the registrydeny (404)Prevents a rug-pulled tool from riding an approved server.
No policies configureddenySecure default; an empty rule set is not permission.
Broker unavailable on a scoped_token decisionCall cannot proceed; the error is returned in place of a credentialBetter no authority than unbounded authority.
Control plane unreachable for a registry refreshLast good snapshot continues to serveThe hot path never depended on the API; a refresh outage degrades freshness, not availability.

Why there is no fail-open switch

The obvious request is a toggle that lets traffic through when we are unavailable. We deliberately do not offer one: a control whose guarantee evaporates exactly when the system is under stress is not a control, and "fail open" is indistinguishable from "not deployed" at the moment it matters.

The supported way to not block is Monitor Mode, which is the default. A tenant observes until enforcement is switched on explicitly, so the choice is made deliberately and up front rather than implicitly during an incident:

PUT /v1/govern/enforcement {"default": "observe"}

In observe the decision is computed and sealed identically — only the consequence is withheld — so the monitor period is real evidence for the enforce period. See Monitor Mode.

4. Change management

How it works
DeploysRolling update with health checks; no in-place mutation of a running task. Observed end-to-end ~4 minutes.
RollbackRedeploy the previous image tag — every release is an immutable, tagged artifact.
Schema changesApplied as a one-off migration task before services roll, so a task never runs against a schema it does not expect.
Infrastructure stateVersioned remote state with locking, so two concurrent changes cannot interleave.
Evidence integrityHash-chained per tenant; verify any time with GET /v1/evidence/verify.

Current limits

Stated plainly, because an operational page that hides them is worth less than one that names them:

  • Sustained throughput under concurrency is not yet published. The latency figures above are single-threaded and exclude network time.
  • One hosted environment. There is no separate multi-region topology today; self-hosting is documented in Self-hosting.
  • Rollback is documented but not yet published with measured timings.