Enforcement point tradeoffs
A decision from the PDP is only as good as the boundary that dispatches on it. The SDK supports three placements for that boundary, so it can be deployed against agents the integrator fully controls, partially controls, or does not control at all.
| Placement | Where it runs | Integrator controls the agent? | Status |
|---|---|---|---|
| PEP — Sidecar | Local egress proxy, one per agent process | Yes | Implemented |
| PEP — Gateway | Shared central proxy, one per fleet | Yes | Design-stage (Phase 5) |
| PEP — Boundary adapters | At whatever boundary is controllable: resource server, MCP proxy, or egress mesh | No | Design-stage (Phase 5) |
Sidecar: strongest guarantee, per-agent operational cost
The sidecar sits on localhost next to one agent process; egress is pinned to it, so a request
never reaches an upstream without a decision first. This is the deployment
the how-to guide and
the tutorial's decision step exercise, and the one
with the most direct evidence: zero requests reach the upstream on a deny or on PDP
unavailability (fail-closed), because forwarding is reachable from exactly one code path in
sidecar/enforce.py. The cost is operational: one sidecar instance per agent process to deploy
and keep running.
Gateway: one choke point, shared fate
A gateway centralizes the same decision-then-forward logic behind one shared proxy instead of one per agent — simpler to operate at fleet scale, at the cost of a single point that must fail closed on its own unavailability (a gateway outage is not allowed to degrade into pass-through). See PEP — Gateway for the designed flow.
Boundary adapters: enforcement without owning the agent
Not every agent an integrator needs to govern is one they can modify — a third-party agent, a
managed connector, an agent runtime they don't operate. Boundary enforcement moves the checkpoint
to whatever the integrator does control: their own resource server, an MCP-native proxy, or an
injected egress mesh. These modes are explicitly ordered by strength, and the weakest —
reduced-guarantee mode (coarse outer scoping plus revocation and edge audit only, no per-call
narrowing) — is required to surface itself as reduced, never as a silent degrade: responses and
logs carry a guarantee_level field so nobody mistakes it for full enforcement. See
PEP — Boundary adapters.
Why all three share one PDP call
Whichever placement is deployed, it asks the same question the same way — see the
architecture overview for how every enforcement point routes
through the same PDP and
Token Exchange Service. This is what keeps "which
enforcement mode is this fleet running" from becoming "which policy engine is this fleet
running" — the enforcement-mode enumeration target
(all three exercised by real integrators, per docs/design-doc.md's Success Criteria) is
meaningful specifically because switching placement never changes the decision logic.
Where to go next
- Deploy the sidecar PEP — the mode you can deploy today
- Deploy the gateway PEP — designed, not yet shipped
- Deploy a boundary adapter PEP — designed, not yet shipped