A preflight for proxy policy

Test the gate before traffic arrives.

Replay synthetic requests, forwarded headers, and mock DNS against Anubis, Caddy, and Nginx-compatible rules. See exactly why each request is allowed, challenged, or blocked.

  • No live DNS
  • No telemetry
  • One binary
Three porcelain gates align over ice as a cobalt bead passes through, visualizing a request crossing a trusted proxy chain.
01 Peer 02 Forwarded chain 03 Policy

Allow monitor.internal

Challenge unknown client

Block anonymous /admin/*

Browser rehearsal

Move the monitor. Watch the contract fail.

This fixture runs entirely in your browser. Change the mock DNS answer or a case expectation, then compare all three adapter profiles.

Nothing leaves this tab. Press Ctrl + Enter to run.

Decision ledger

Ready

Three adapters are waiting at the gate.

Run the fixture to compare decisions.

One binary. Zero calls home.

Put the rehearsal in CI.

Readable output for review; stable JSON and honest exit codes for scripts.

cargo install --git https://github.com/B-Divyesh/sf-proxy-policy-rehearsal --bin ppr
CASE                 ADAPTER  CLIENT          DECISION   EXPECTED
monitor-via-proxy    anubis   203.0.113.42    allow      allow  ✓
spoofed-forwarded-ip caddy    198.51.100.9    challenge  challenge  ✓
anonymous-admin      nginx    198.51.100.9    block      block  ✓

9 passed · 0 failed · 0 unchecked · 9 decisions

Portable on purpose

One small rule vocabulary. Three documented profiles.

Rehearse the shared surface operators actually rely on. Unsupported native semantics are named, never approximated silently.

01

Anubis

Models client IP, request path, method, and header conditions commonly expressed in policy CEL.

Not nested CEL or bot weights

02

Caddy

Models trusted proxy client IP derivation and the portable request matcher subset.

Not handler order or plugins

03

Nginx

Models real_ip trust with geo/map-style request decisions.

Not location precedence or regex

Deploy with evidence

Production is a poor rehearsal room.

Read the docs on GitHub