Skip to main content
The PEP sits between the agent and its side effects. The agent proposes a step; the PEP intercepts it, sends the step’s context to the PDP, and enforces the verdict that comes back. Nothing consequential runs until that round-trip resolves.

The wrap pattern

You do not rewrite the agent. You wrap the points where its output crosses a boundary: the five enforcement stages for text, and the tool dispatcher for actions. Concretely, wherever your runtime dispatches a tool call, you call the PEP first and only execute on ALLOW:
Text stages work the same way with checkInput, checkContextEgress, checkOutput, and checkDelivery. See the TypeScript and Kotlin SDK pages for full signatures.

Interception is selective

Interception does not mean every call pays a policy tax. Latches are dormant by default: the PDP matches the stage, the content, and the normalized tool name against each attached policy, and only a governed step engages a latch.
  • A call to a routine tool such as order_status matches no latch and resolves ALLOW.
  • A call to a consequential tool such as refund_payment engages the latch that governs it, and the full verdict logic runs.
See Latching for the matching rules and tool-name normalization.

What crosses to the PDP

Each interception becomes one POST /api/policy/authorize request. The PDP never calls into your runtime; it decides entirely on the payload the PEP sends:

What comes back, and how it is enforced

The response is a single PolicyDecision. The PEP enforces it before the step continues: The permitId is what makes interception enforceable end to end: the side-effecting service refuses to run without a fresh permit, so a blocked or escalated action cannot leak through a code path that skipped the PEP. If the PDP is unreachable or the response is ambiguous, the PEP synthesizes a BLOCK. See Fail-closed.

Next: audit and evidence

Every one of these decisions becomes a signed, tamper-evident record.