# Rules and managed groups

> Labels in, actions out: how AgentGate's WAF-style rules turn signals into allow, challenge, block, drop or count.

AgentGate decides like a web application firewall. Every request it
evaluates goes through two stages.

## 1. Signals become labels

Signal sources look at the request and attach **labels** and **scores**:

| Example label | Means |
| --- | --- |
| `agentgate:proof:missing` | no proof of work was sent |
| `agentgate:signal:machine_cadence` | typing rhythm looks machine-generated |
| `agentgate:env:webdriver` | the browser reports `navigator.webdriver` |
| `agentgate:tls:non_browser` | the TLS fingerprint is not a browser's |
| `agentgate:rate:ip_soft_exceeded` | the address is over its soft rate budget |
| `agentgate:agent:verified:chatgpt` | a valid Web Bot Auth signature from ChatGPT |
| `agentgate:ip:cloud:aws` | the address is in AWS's published ranges |
| `agentgate:sdk:late_init` | the page called `execute()` without `init()` |

Scores include `content`, `bot_risk` and `ip_reputation`.

## 2. Rules pick an action

An **ordered rule set** matches on labels, label prefixes, score
thresholds and the request itself (IP sets, country, ASN, cloud, Tor,
headers, query, path, method, JA4 fingerprint, verified agent), combined with
`and` / `or` / `not`. Rules can be rate-based and limited to routes.

| Action | Effect |
| --- | --- |
| `allow` | admit |
| `challenge` | ask for the step-up check (or a new token, at the gateway) |
| `block` | refuse, optionally with a custom response |
| `drop` | answer like an acceptance, deliver nothing |
| `count` | add the label `agentgate:rule:<name>` and continue |

The first matching rule whose action is not `count` decides; with no match
the rule set's `default_action` applies.

```json
{"name": "form_flood", "action": "block", "routes": ["/submit"],
 "rate": {"limit": 20, "window_seconds": 60, "keys": ["ip_prefix24"]},
 "response": {"status": 429, "retry_after": 60, "body": {"error": "rate_limited"}}}
```

## Managed rule groups

You rarely write rules from scratch. **Managed groups** are versioned,
published rule sets you reference by name and version:

- `agentgate-core@1`: the built-in browser-check rules, including per-agent
  policy;
- `agentgate-agents@1`: Web Bot Auth policy for the agent API;
- `agentgate-gateway@1`: gateway authorization (signatures, rate budgets,
  tokens, required browser evidence);
- `agentgate-bot-control@1`: user-agent and crawler IP checks;
- `agentgate-anonymity@1`: Tor, datacenter and IP reputation.

The default rule set is `agentgate-core@1`, `agentgate-agents@1` and
`agentgate-gateway@1`, in that order.
Published versions never change, so an upgrade is an explicit edit, and
`overrides` can switch single rules to `count` while you measure them.

## Where to go next

- The full language: [Rule language](/docs/rules)
- Every group and its rules: [Managed rule groups](/docs/managed-rule-groups)
- IP data behind `country`, `asn`, `cloud`, `tor` and crawler checks:
  [Threat intelligence](/docs/threat-intelligence)
