# Enforcement Mode

Enforcement mode lets you safely deploy security rules without affecting live traffic. New rules can evaluate in the background while you review their impact, then promote them to active enforcement when you are confident in the results.

## How It Works

Enforcement mode is configured at two levels:

* **Policy level** -- `enforce` (default) or `monitor`
* **Rule level** -- `inherit` (default), `enforce`, or `monitor`

The effective mode for each rule is determined by combining both settings. The key principle is that **monitor always wins** -- if either level is set to monitor, the rule runs in monitor mode.

| Policy Mode | Rule Mode | Effective Mode |
| ----------- | --------- | -------------- |
| `monitor`   | `inherit` | monitor        |
| `monitor`   | `enforce` | monitor        |
| `monitor`   | `monitor` | monitor        |
| `enforce`   | `inherit` | enforce        |
| `enforce`   | `enforce` | enforce        |
| `enforce`   | `monitor` | monitor        |

This design ensures that a policy-level monitor cannot be overridden by individual rules, making it safe to put an entire policy into observation mode.

## What Happens in Monitor Mode

When a rule runs in monitor mode:

1. The rule **evaluates normally** -- pattern matching, classification, and all other logic runs exactly as it would in enforce mode.
2. If triggered, it appears in the `triggered_rules` array of the response with `"monitoring": true`.
3. Rule statistics (trigger counts, match counts) **update as usual**.
4. The rule's decision is **suppressed** -- no blocking or masking is applied to the message.

The message passes through as if the rule did not exist, but you get full visibility into what *would have* happened.

### Example: Triggered Rule in Monitoring Mode

In a proxy response or webhook payload, a monitoring rule appears like this:

```json
{
  "triggered_rules": [
    {
      "rule_id": "b3f1a2c4-...",
      "rule_name": "block-profanity",
      "decision": "block",
      "monitoring": true
    }
  ],
  "blocked": false
}
```

The `decision` field shows what *would* have happened. The `monitoring: true` flag and `blocked: false` confirm the decision was suppressed.

## Typical Deployment Workflow

{% stepper %}
{% step %}

### 1. Deploy in Monitor Mode

Start by creating a policy in monitor mode to observe how rules behave against real traffic:

```bash
curl -X POST https://your-instance.example.com/api/v1/policies \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Content Security",
    "enforcement_mode": "monitor"
  }'
```

{% endstep %}

{% step %}

### 2. Review Triggers

Let the policy run for a period of time, then check rule statistics and logs. Look for:

* **Trigger frequency** -- is the rule firing as often as you expect?
* **False positives** -- are legitimate messages being flagged?
* **Coverage** -- are there messages that should match but do not?

Use the Analytics and Logs pages, or query the API for rule stats.
{% endstep %}

{% step %}

### 3. Promote to Enforce Mode

Once you are satisfied with the rule behavior, switch the policy to enforce mode:

```bash
curl -X PUT https://your-instance.example.com/api/v1/policies/{policy_id} \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enforcement_mode": "enforce"
  }'
```

All rules with `inherit` mode will immediately begin enforcing their decisions.
{% endstep %}

{% step %}

### 4. Gradual Rollout for New Rules

When adding new rules to an enforcing policy, set individual rules to monitor mode while keeping the policy in enforce:

```bash
curl -X POST https://your-instance.example.com/api/v1/rules \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "New Prompt Injection Rule",
    "rule_type": "lightweight_model",
    "policy_id": "POLICY_ID",
    "direction": "inbound",
    "decision": "block",
    "enforcement_mode": "monitor",
    "config": {
      "model_id": "sentinel_v2",
      "threshold": 0.80
    }
  }'
```

This rule evaluates every inbound message and reports triggers, but does not block anything. Once validated, update the rule to `inherit` or `enforce` to activate it:

```bash
curl -X PUT https://your-instance.example.com/api/v1/rules/{rule_id} \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enforcement_mode": "inherit"
  }'
```

{% endstep %}
{% endstepper %}

## API Examples

### Create a Policy in Monitor Mode

```bash
curl -X POST https://your-instance.example.com/api/v1/policies \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "new-threat-policy",
    "enforcement_mode": "monitor"
  }'
```

### Switch a Policy from Monitor to Enforce

```bash
curl -X PUT https://your-instance.example.com/api/v1/policies/{policy_id} \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enforcement_mode": "enforce"
  }'
```

### Create a Rule with Monitor Mode

```bash
curl -X POST https://your-instance.example.com/api/v1/rules \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "experimental-injection-detector",
    "rule_type": "lightweight_model",
    "policy_id": "POLICY_ID",
    "direction": "inbound",
    "decision": "block",
    "enforcement_mode": "monitor",
    "config": {
      "model_id": "sentinel_v2",
      "threshold": 0.70
    }
  }'
```

## Integration Notes

### Drop-in Proxy

Enforcement mode is transparent to clients. Whether a rule is in monitor or enforce mode, the proxy API behaves the same way -- no client-side changes are needed. The only difference is whether matched rules actually affect the message content.

### Async Jobs

When a monitored rule fires during an async job, the webhook payload includes the monitoring flag (`"monitoring": true`) in `triggered_rules` and `blocked` remains `false`. Your webhook handler can use this information for alerting or dashboarding without changing its processing logic.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.collieai.io/security-rules/enforcement-mode.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
