Skip to content

Policy engine

The Policy engine runs the pipeline steps on every governed call.

Each call (LLM or tool) flows through the engine: before-during-after steps fire in order, the engine returns allow (with a signed mandate) or deny (with a reason).

This is the hot-path arm of Policy. Already shipped as tappass/gateway/'s 32-step pipeline.

Takesa call (LLM request or tool invocation) + the agent's Compiled Policy's pipeline steps
Doesruns the pipeline in order: before → during → after
Outputsallow (signed Ed25519 mandate) or deny (with reason + audit row)
Where it runsserver-side, on every governed call (the gateway path)
Statusshipped (tappass/gateway/, 32 steps wired in)

Each call goes through three phases:

┌─────────────────────────────────────┐
│ BEFORE-THE-CALL │
│ │
│ • detect PII / secrets / exfil │
│ • capability-token validation │
│ • budget / rate gate │
│ • prompt-injection scan │
│ • policy_version match check │
└────────────────┬────────────────────┘
│ allow ⇒ continue / deny ⇒ stop
┌─────────────────────────────────────┐
│ DURING-THE-CALL │
│ │
│ • call upstream (LLM provider / │
│ tool) │
│ • sign mandate (Ed25519) │
│ • write audit row (hash-chained) │
└────────────────┬────────────────────┘
┌─────────────────────────────────────┐
│ AFTER-THE-CALL │
│ │
│ • output scan (PII redact, secret │
│ redact, exfil-pattern scan) │
│ • response filter / sanitize │
│ • trace finalize (sign chain) │
└─────────────────────────────────────┘

Each step is a small unit (a "PipelineStep") that takes a call context and returns a decision. The engine composes them in order. The set of steps and their config come from the Compiled Policy.

When an agent calls the LLM (or a tool), the request hits the gateway. The gateway loads the agent's Compiled Policy (cached from the last sync push), reads the pipeline-step list, and runs each step in order with the call context.

If any before or during step returns deny, the call is rejected — the agent receives a structured error with the reason; an audit row is written; no upstream call happens.

If all steps allow, the gateway calls the upstream (LLM provider, tool, MCP server), then runs after steps on the response before returning it to the agent.

The Policy engine is the same machinery for every governed call — no per-tool special casing. The variance is in the Compiled Policy each agent has.

  • Server-side, in tappass/gateway/ — already shipped as the 32-step pipeline.
  • Per-call latency target: P50 < 50ms, P99 < 200ms (measured against existing pipeline).
  • Caches the Compiled Policy per (org_id, sandbox_id, policy_version), invalidated on sync push.
  • Reads Compiled Policy — gets the pipeline-step list from there.
  • Writes signed audit events (consumed by hash-chain audit + drift detection).
  • Sister engine: Policy compiler — produces what this engine reads.