> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squasher.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Detection rules

> Manage detection rules as code: the built-in Sigma and Agent Threat Rules pack, your own rule packs, validation, and backtests over past logs.

Squasher checks your connector logs, web server spans, and AI agent spans against detection rules
when the data arrives. Each match is a security finding. Detection findings never page.

You manage the rules as code. Each project has the built-in pack and up to 20 packs of its own.
You can check a rule before you save it, and you can run a rule over past logs to see what it
would have found.

## Rule packs

| Pack | Contents | Changes |
| - | - | - |
| `builtin` | Curated SigmaHQ rules (Detection Rule License 1.1, each finding shows the rule author and id), Agent Threat Rules (MIT), and a small set of Squasher rules. Always on. | Read only. |
| A custom pack | Up to 50 rule files of your own, in the Sigma format or the Agent Threat Rules (ATR) format. | Create, change, turn off and on, and delete. |

A change to a custom pack applies within about 60 seconds. A turned-off pack keeps its rules and
does not run.

All turned-on custom packs of a project together hold at most 20 packs, 200 rule files, and 4 MiB
of rule YAML. A create, change, or turn-on that goes past one of these limits fails with `409`. Turn
off a pack or remove rule files first.

## Rule formats

| Format | Runs on |
| - | - |
| `sigma` | The Sigma log source of the rule: `product: okta, service: okta`, `product: github, service: audit`, `product: aws, service: cloudtrail` (connector logs), or `category: webserver` (HTTP server spans). |
| `atr` | AI agent spans (OpenTelemetry GenAI attributes): user input, agent output, tool name, tool arguments, tool result, and tool description. |

A Sigma field name reads the mapped attribute of the log first, then the raw vendor record of the
connector log, so a rule written for the vendor's field names works without changes. Each rule
needs an `id` that is unique in its pack and a `title`.

```yaml okta_admin_token.yml theme={null}
title: API token created by an admin
id: acme-okta-admin-token
logsource:
  product: okta
  service: okta
detection:
  selection:
    eventType: system.api_token.create
  condition: selection
level: high
```

## Validate a rule

Validation compiles each file with the same engine that runs at ingest and returns one error per
file that does not compile. It stores nothing.

```bash theme={null}
squasher detections validate --project $SQUASHER_PROJECT_ID --file okta_admin_token.yml
```

Create and update also validate every file, and refuse the change with the errors when a file
does not compile. Add `--dry-run` to see the validation without a change.

```bash theme={null}
squasher detections create --project $SQUASHER_PROJECT_ID --name okta --file okta_admin_token.yml
squasher detections disable --project $SQUASHER_PROJECT_ID <PACK_ID>
squasher detections enable --project $SQUASHER_PROJECT_ID <PACK_ID>
squasher detections delete --project $SQUASHER_PROJECT_ID <PACK_ID> --dry-run
```

## Backtest a rule

A backtest runs a pack, or rule files that you have not saved, over the connector logs of a past
window. The window is at most 7 days and a backtest reads at most 10,000 log events. A backtest
stores nothing and makes no findings.

```bash theme={null}
squasher detections backtest --project $SQUASHER_PROJECT_ID --file okta_admin_token.yml \
  --from 2026-10-25T00:00:00Z --to 2026-11-01T00:00:00Z
squasher detections backtest-get --project $SQUASHER_PROJECT_ID <JOB_ID>
```

The job reports its status (`queued`, `running`, `succeeded`, `failed`, or `cancelled`) and
progress. A finished job lists the events read, the matches of each rule with up to 5 sample
timestamps, and `truncated` when the window held more events than a backtest reads. Stop a job
with `squasher detections backtest-cancel`.

A backtest reads logs with the same limits as other security queries: the project's own logs
only, the security attributes only, and the project's query budget. The budget covers the whole
job, not each read. A project runs at most 2 backtests at a time, and one backtest runs for at most
240 seconds. A job that passes the budget or the time limit fails with `budget_exceeded` or
`time_limit_exceeded` and keeps the partial result.

## Related

* [Detections API](https://docs.squasher.ai/api-reference/detections.md)
* [Ingest rules](https://docs.squasher.ai/features/ingest-rules.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.