# Audit log (/docs/dashboard/audit-log)



The **Audit*&#x2A; tab is the record of what the firewall decided. Its own description is the clearest
summary in the product: &#x2A;"Each row is one firewall decision about a call — not the call itself.
Allowed traffic is not listed. Outcome is what happened (Would... means the call still ran). Mode
is the rule's setting, not whether the call was stopped."*

## What it's for [#what-its-for]

Answering "why was this blocked?" and its far more common sibling, "why wasn't this blocked?".

## The columns [#the-columns]

| Column            | Shows                                                                     |
| ----------------- | ------------------------------------------------------------------------- |
| **Time**          | When the decision was made.                                               |
| **Outcome**       | What happened — see the vocabulary below.                                 |
| **Mode**          | The rule's setting, Dry-run or Enforce. Not whether the call was stopped. |
| **Rule**          | Which rule decided.                                                       |
| **Entity**        | The pool it applied to — a user, a plan, a tag value, a trace.            |
| **User**          | The `user_id` on the call.                                                |
| **Model**         | The model involved.                                                       |
| **Spent / limit** | How far into the limit that pool was.                                     |
| **Action**        | Block, notify or reroute.                                                 |

Tabs above the table narrow it: **All · Loops · Denied · Routing · Dry-run**.

## The outcome vocabulary [#the-outcome-vocabulary]

| Real             | Counterfactual      | Meaning                                                      |
| ---------------- | ------------------- | ------------------------------------------------------------ |
| **Denied**       | **Would deny**      | A block. The counterfactual row means the call ran anyway.   |
| **Rerouted**     | **Would reroute**   | A model swap, or one that didn't happen.                     |
| **Loop blocked** | **Would stop loop** | A loop rule stopping a run, or recording that it would have. |

Other outcomes have no would-be twin: **Budget exceeded**, **Notified**, **Loop detected** and
**Reroute rejected**.

The event catalog is wider than the page: **Rule matched**, &#x2A;*Armed (block)**, &#x2A;*Armed
(reroute)**, **Released** and **Loop blocked** are recorded, but the tabs deliberately don't
list them — see *What to look for* below.
*Armed* means the pool crossed its limit and is now on the stopped list; *Released* means it came
off, because the window reset or the rule was demoted or deleted.

## The attribution chip — the best thing on this page [#the-attribution-chip--the-best-thing-on-this-page]

Every counterfactual row is amber and carries a chip naming exactly which switch was open:
**SDK & rule in dry-run**, **SDK in dry-run**, or **Rule in dry-run**. If you only ever look at one
place to understand why a rule isn't stopping anything, look here.

The page says it directly: &#x2A;"Would... happens when the SDK, the rule, or both are in dry-run —
hover Outcome to see which. Mode is only the rule's setting. The Dry-run tab is rows whose rule is
Dry-run, not every Would... row."*

## What to look for [#what-to-look-for]

* **Rows all say *Would deny* with "SDK in dry-run"** — your rules are armed but your app isn't.
  Initialize the SDK with `firewall: "enforce"`.
* **The same chip says "Rule in dry-run"** — your app is armed; promote the rule.
* **Lots of *Reroute rejected*** — the rule ordered a swap and the SDK could not apply it. These
  rows are in **All**, not on the **Routing** tab, which lists only reroutes that happened.
* **No loop *blocks* anywhere on this page** — and no **Armed** / **Released** / **Rule matched**
  rows either. That's deliberate: **All** and **Dry-run** show a curated set of six event types
  (denied, rerouted, budget exceeded, notified, loop detected, reroute rejected), and the other
  three tabs each filter to a single type — **Loops** is loop *detections* only. A loop *block*
  is the per-request repeat that follows a detection, and it would bury everything else. To see
  the blocks, open the run on [Traces](/docs/dashboard/workflows-sessions-traces): each trace
  carries its loop count, and the loop leaderboards count blocks directly.

## Next [#next]

<Cards>
  <Card title="Dry-run vs enforce" href="/docs/concepts/dry-run-vs-enforce" description="The two-switch model these rows are evidence of." />

  <Card title="Unexpected blocks" href="/docs/troubleshooting/unexpected-blocks" description="Working backwards from a denial you didn't expect." />

  <Card title="Dry-run & Routing" href="/docs/dashboard/dry-run-and-routing" description="Projected impact per rule, and every model swap." />
</Cards>
