# Firewall & Budgets (/docs/rules/overview)



Firewall rules are how you tell TokenPolice what to do about an LLM call. Each rule is a
**filter** (which calls it watches), an optional **limit** (how much those calls are allowed to
spend), and an **action** (block, notify, or reroute).

You'll find them at [app.tokenpolice.ai/firewall](https://app.tokenpolice.ai/firewall), on a
page titled **Firewall & Budgets**.

<Callout type="info">
  **A budget *is* a firewall rule.** There is no separate Budgets feature in TokenPolice. When
  the product says "budget" it means a firewall rule that has a spending limit — an amount, a
  unit, a reset period, and what happens when the limit is crossed. One object, not two.
</Callout>

## Two kinds of rule [#two-kinds-of-rule]

The page has two tabs:

| Tab                                     | What it does                                                                                                                             |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Cost & access*&#x2A; &#x2A;(default)* | Cap spend, block a user or a whole plan, or reroute to a cheaper model.                                                                  |
| **Runaway loops**                       | Catch a single agent run that's stuck repeating itself or blowing past a hard ceiling. See [Loop detection](/docs/rules/loop-detection). |

Each tab has the same two buttons: **New rule from template** (opens the gallery) and
**Custom rule** (opens the builder).

## What a rule is made of [#what-a-rule-is-made-of]

| Setting          | What it means                                                                                                                         |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Name**         | Required, and unique within the project. Saving a rule with an existing name **updates that rule** rather than creating a second one. |
| **Filter (IF)**  | Which calls the rule watches. See [Filter vs apply-to](/docs/rules/match-vs-groupby).                                                 |
| **Apply to**     | Whether the limit is one shared pool or a separate copy per user, per plan, per tag value.                                            |
| **Limit**        | An amount plus a unit — **USD**, **tokens**, or **requests**. Optional.                                                               |
| **Reset period** | A calendar period (hour, day, week, month), a sliding window in minutes, or lifetime.                                                 |
| **Action**       | **Block**, **Notify**, or **Reroute**. See [Actions](/docs/rules/actions).                                                            |
| **Mode**         | **Dry-run** or **Enforce** — for Block and Reroute rules only.                                                                        |

## A rule does not need a limit [#a-rule-does-not-need-a-limit]

A rule with no limit is **unconditional**: it acts on *every* call the filter matches, with no
counting involved. "Block every call from `plan = free`" is an unconditional rule. In the custom
builder this is the **Unconditional** checkbox, and Reroute rules default to it — uncheck it to
turn the rule into a budget instead, so it only fires once the pool crosses the limit.

In the rules table, a rule with no limit shows **Unconditional** (reroute) or **No Limit**.

## Every block and reroute rule starts in Dry-run [#every-block-and-reroute-rule-starts-in-dry-run]

A new Block or Reroute rule is created in **Dry-run** — it evaluates every matching call and
records what it *would* do, but never blocks or reroutes. Nothing your users do is affected
until *both* the rule and your SDK are set to enforce.

<Callout type="info">
  Read [Dry-run vs enforce](/docs/concepts/dry-run-vs-enforce) first. A rule acts only when the
  rule's mode **and** your app's `firewall` mode both say enforce — so you can watch a rule on
  real traffic before it can ever affect a request. The dashboard's
  [Dry-run tab](/docs/dashboard/dry-run-and-routing) shows what each watching rule would have done.
</Callout>

**Notify rules have no mode at all.** They never block anything, so there is nothing to gate —
they show a dash in the Current Mode column and cannot be promoted to Enforce.

## Turning a rule on, and turning it off [#turning-a-rule-on-and-turning-it-off]

In the rules table, each row's **Manage** column has one button:

* A Dry-run rule shows **Switch to Enforce*&#x2A;. It asks you to confirm first: &#x2A;"is in Dry-run
  right now. Switching to Enforce means it starts taking real effect on your live traffic
  immediately."* — and warns there is **no undo on side effects**: you can switch back any time,
  but anything blocked or rerouted in the meantime has already happened.
* An Enforce rule shows **Switch to Dry-run**, which applies immediately with no confirmation and
  also clears anything that rule currently has blocked or rerouted.

If a rule is set to Enforce but your app's SDK last reported `dry_run` or `off&#x60;, the page shows a
banner — &#x2A;*"Rules set to Enforce, app in Dry-run"*&#x2A; (or &#x2A;"app in Off"*) — telling you the rules
evaluate but never act.

### Project-wide emergency stop [#project-wide-emergency-stop]

Project Settings has a **Demote all rules to Dry-run** button: every active Block/Reroute rule in
the project drops to Dry-run and anything currently blocked or rerouted is cleared. Rule
configuration is kept, so you can promote individual rules again afterwards. You confirm by
typing the project name. See [Settings & billing](/docs/dashboard/settings-and-billing).

## Editing and deleting [#editing-and-deleting]

There is no in-place edit for a cost and access rule. To change a limit or a condition, either
build a **Custom rule** with the **same name** — which overwrites the existing rule — or delete
it and create it again.

Deleting is immediate, but the dashboard notes it can take up to **60 seconds** to propagate to
every SDK.

## Changes go live right away [#changes-go-live-right-away]

When you save, promote, demote, or delete a rule it reaches the firewall almost immediately —
there is no deploy step and nothing to restart in your app.

## Build your first rule [#build-your-first-rule]

<Cards>
  <Card title="Start from a template" href="/docs/rules/templates" description="All 17 ready-made rules, and the fields each one asks for." />

  <Card title="Filter vs apply-to" href="/docs/rules/match-vs-groupby" description="Which calls, who gets their own budget, and how the window resets." />

  <Card title="Actions" href="/docs/rules/actions" description="Block, notify, or reroute — and what your app sees." />

  <Card title="Loop detection" href="/docs/rules/loop-detection" description="Stop one agent run that goes in circles or runs away." />

  <Card title="See a BLOCK rule in action" href="/docs/sample-apps/budget-aware-rag" description="A sample app that sets a per-session BLOCK rule and shows the firewall stop a session." />
</Cards>
