TokenPolice
Docs
Core concepts

Dry-run vs enforce (the two dials)

An action fires only when both the SDK firewall mode and the per-rule execution mode say enforce. Default is dry-run.

TokenPolice has two dials, and a rule only acts — blocks, reroutes — when both are turned to enforce. This is deliberate: it lets you watch what a rule would do before you let it do anything.

Dial 1 — the SDK firewall mode

Set once, app-wide, in tp.init(). It has three settings:

firewallWhat happens
"dry_run" (default)Runs the full check on every call and records what it would do — but never blocks or reroutes. Watch mode.
"enforce"Same checks, but now actions actually fire.
"off"No checks at all. Calls are still logged for your dashboard, but no rule can ever act.
tp.init(
    api_key=os.environ["TOKENPOLICE_API_KEY"],
    base_url="https://collect.tokenpolice.ai",
    firewall="dry_run",   # start here; flip to "enforce" when ready
)

Dial 2 — the rule's execution mode

Every firewall rule you create in the dashboard has its own mode: Dry-run (the default for a new rule) or Enforce. This lets you roll out one rule at a time — flip a single rule to Enforce while the rest keep watching.

Both must say enforce

An action only fires when the SDK dial and that rule's dial both say enforce:

SDK firewallRule modeResult
dry_runDry-runLogged as would-block — nothing happens
dry_runEnforceLogged as would-block — nothing happens
enforceDry-runLogged as would-block — nothing happens
enforceEnforceThe action fires (e.g. TokenPoliceBlockedError)
off(either)No check runs at all

In any dry-run combination, TokenPolice records the decision as a would-block so you can see the impact in the dashboard — it just doesn't touch your call. There's no separate "shadow" mode; dry-run is the watch mode.

Notify rules have no dial. A rule whose action is Notify doesn't change your call, so there's nothing to hold back: it has no Enforce / Dry-run setting and it sends its alert whichever way the SDK dial is set. The two dials govern the actions that touch traffic — Block and Reroute.

The rollout you'll actually do

Start with firewall="dry_run". Add your rules. Watch the would-block entries pile up in the dashboard and confirm they match what you expect.

Flip the one rule you trust to Enforce in the dashboard. Nothing changes yet — the SDK dial is still dry_run.

When you're ready to go live, set firewall="enforce". Now every Enforce rule acts; any rule still on Dry-run keeps watching.

Next