---
title: Enforcement modes
description: OBSERVE, SIMULATE and ENFORCE — what each one actually does, and the one thing about OBSERVE that surprises everyone.
label: Enforcement modes
---

Enforcement mode lives on the **environment**, not on a policy or an agent. One
setting governs everything in that environment, which is what makes it a safe
thing to change and an auditable thing to have changed.

Three modes, meant to be walked in order.

:::diagram journey | Each stage tells you what the next one will refuse, before it refuses it.
`OBSERVE` executes everything and records the divergences, which is how you
learn what will break. `SIMULATE` refuses for real and executes nothing, which
is where policy correctness gets settled. `ENFORCE` refuses for real. Moving
backwards is allowed, and it needs a reason, step-up authentication and a
`CRITICAL` audit event.
:::

## What each mode does

| | `OBSERVE` | `SIMULATE` | `ENFORCE` |
| --- | --- | --- | --- |
| Pipeline stages 1–9 run | yes | yes | yes |
| A refusal stops the action | **no** | yes | yes |
| Credential brokered | yes | no | yes, if allowed |
| Tool actually executes | **yes** | no | yes, if allowed |
| Approval can be created | no | no | yes |
| `shadow.decision` populated | yes | yes | — |
| Decision recorded in audit | yes | yes | yes |
| Protects anything | **no** | n/a | yes |

## OBSERVE executes everything

:::danger This is the thing to understand
In `OBSERVE`, Veefore runs the full pipeline, computes a decision, records it —
and then lets the action proceed regardless. An action that `ENFORCE` would
`BLOCK` **executes** in `OBSERVE`. It reaches your downstream system. It has
whatever side effect it was going to have.

`OBSERVE` is instrumentation. It is not a safety setting, and an environment
left in `OBSERVE` is an unprotected environment with good logs.
:::

The two fields that matter:

```json
{
  "mode": "OBSERVE",
  "decision": "ALLOW",
  "outcome": "OBSERVED",
  "allowed": true,
  "shadow": {
    "decision": "BLOCK",
    "reason": "Destructive database operations are not permitted through an agent."
  }
}
```

- `decision` is the **effective** decision. In `OBSERVE` it is `ALLOW`.
- `shadow.decision` is what **enforcement would have done**.

When those two disagree, you are looking at something that will break the moment
you promote. That divergence is the whole value of the mode: it is a list of
work to do, generated from real traffic rather than guessed at.

## SIMULATE is the honest middle

`SIMULATE` runs the full pipeline and executes nothing. No credential is
brokered, no downstream call is made, no external side effect occurs anywhere.
Refusals are real refusals.

This is the mode for shaking out policy correctness, because a mistake costs you
a wrong line in a report rather than a wrong row in a database. It is also what
`veefore deploy` preflight replays your observed traffic through.

## ENFORCE refuses

Full pipeline, real refusals, real execution for what is permitted, approvals
created where policy asks for them. This is the mode Veefore exists for.

## Moving between modes

```bash
veefore deploy --mode ENFORCE --reason "Refund policy reviewed in CHG-4411"
```

or over the API:

```http
POST /v1/environments/{environmentId}/gateway-mode
```

`veefore deploy` is the better path because of what it does first:

1. **Preflight.** Checks for agents with no policy coverage, dangerous tools permitted only by a default decision, expired trust evidence, and credentials overdue for rotation.
2. **Replay.** Re-evaluates your recent observed traffic in the target mode and shows you exactly which calls start being refused — before anything changes.
3. **Confirm.** Shows the blast radius and asks.
4. **Authorise.** Requires a reason and step-up authentication.

The replay is the step that earns its keep. "Enabling enforcement will refuse 14
of your last 400 actions, and here they are" is a decision you can make.

## Going backwards

Allowed, and never quiet.

Reducing enforcement requires `environment:set_mode`, a recorded reason, step-up
authentication, and it writes a `CRITICAL` audit event. The Security Center
surfaces it, and a webhook fires if you have one subscribed.

The asymmetry is deliberate. Tightening is routine. Loosening is the action an
attacker would want, and the action a team under pressure reaches for at 2am, so
it leaves a mark either way.

:::warning Mode is not a kill switch
If something is actively going wrong, dropping to `OBSERVE` is the **worst**
available option — it stops refusing anything while leaving everything running.

Use the controls built for it: `POST /v1/environments/{id}/pause` stops all
protected execution in the environment, and `POST /v1/agents/{id}/pause` stops
one agent. Both are immediate. See
[Emergency controls](/operate/emergency-controls).
:::

## Per-environment, deliberately

Each environment has its own mode, so the normal shape is:

| Environment | Mode | Why |
| --- | --- | --- |
| Development | `SIMULATE` | Policy feedback with no side effects |
| Staging | `ENFORCE` | Behaves like production, so surprises happen here |
| Production | `ENFORCE` | Obviously |

A new environment starts in `OBSERVE` so that adding Veefore to a running system
cannot break it on day one. The expectation is that you leave `OBSERVE` quickly.
`veefore doctor` and the Security Center both flag a production environment
sitting in `OBSERVE`, because that is a finding and not a configuration.

## Knowing when you are ready

Promote when all of these are true:

- `shadow.decision` has not diverged from `decision` on traffic you consider correct for several days.
- Every divergence you did see is either a policy you intended or a bug you fixed.
- `veefore doctor --strict` is clean.
- Every policy's test cases pass.
- Someone knows what to do when an approval request appears, and the approval queue has an owner.

That last one is the one teams forget. `ENFORCE` with `REQUIRE_APPROVAL` rules
and nobody watching the queue is just a slower kind of blocked.

## Related

:::cards

:::card Start in OBSERVE | /journey/observe
What to look at first, and what the divergences mean.
:::

:::card Move to ENFORCE | /journey/enforce
The promotion itself, step by step.
:::

:::card Emergency controls | /operate/emergency-controls
What to actually use when something is going wrong.
:::

:::card Tenancy API | /reference/api/tenancy
Mode changes and environment pause.
:::

:::
