An Attack Simulation Platform for detection engineering.
Detonate attacks, verify the alerts fire, and measure exactly which detections you're testing β across multiple clouds.
Detection rules rot silently. A field gets renamed, a log source drifts, an index mapping changes β and the alert you were counting on simply stops firing. You don't find out until the breach.
SimRun closes that gap. It runs real attack techniques against your environment, confirms the detections you expect actually fire in your SIEM, and tracks which of your rules are tested and which are blind spots.
It's not a script you wire into CI and forget. It's a platform:
- π― Coverage you can see. SimRun joins your live Elastic detection rules against your scenarios and their latest pass/fail result, then reports a coverage percentage. You learn what you aren't testing β not just whether one test passed. β Rule Coverage
- βοΈ Multiple clouds, multiple accounts. First-class connectors for AWS, GCP, Azure, and Kubernetes, each backed by managed, encrypted secret groups and selectable per scenario.
- π§ͺ Three ways to exercise a detection. Detonate a real attack, inject a crafted log to confirm a rule is wired up without touching infrastructure, or collect the raw logs an attack produced to build the next rule.
- π¦ A pack ecosystem. Simulations ship as versioned, shareable bundles with a clean Go SDK. Use the first-party packs, wrap Stratus Red Team, or author your own. β Ecosystem
- π₯οΈ Built to operate. Web UI, REST API, and WebSocket interface; PostgreSQL persistence; scheduled runs; optional multi-user OAuth. It all ships as a single Go binary with the SvelteKit UI embedded.
SimRun is primarily focused on Elastic Security β that's where coverage analysis, injection, and log collection are richest. Datadog security signals are supported as a matching backend.
An Assessment is a saved set of scenarios. Running it creates a Run, which executes every scenario in parallel. Each scenario triggers some activity and then asserts that an expected alert appears in your SIEM before a timeout.
flowchart LR
A[Assessment<br/>scenarios] -->|run| B(Run)
B --> S1[Scenario 1]
B --> S2[Scenario 2]
B --> S3[Scenario N]
S1 --> D{Trigger}
D -->|detonate| E[Real attack<br/> from SimRun pack]
D -->|inject| F[Crafted log<br/>into Elasticsearch]
E --> M[Matcher polls SIEM<br/>until alert fires or timeout]
F --> M
M --> R[(Results + Coverage<br/>Postgres)]
E -.optional.-> C[Collector<br/>gathers related logs]
C --> R
Every detonation gets a UUID that SimRun reflects into the generated activity wherever possible (user-agent strings), so an alert maps unambiguously back to the exact attack that caused it.
β Full vocabulary in Concepts.
Build scenarios visually in the assessment editor, or write the YAML directly β the editor toggles between a forms-based Builder and raw YAML. This scenario detonates a pack simulation in AWS and asserts the matching Elastic Security rule fires:
targets:
aws: prod-aws # an AWS connector you configured in the UI
scenarios:
- name: S3 public access block disabled
detonate:
simrunDetonator:
pack: simrun-base-pack
simulation: aws.s3-disable-public-access-block
expectations:
- timeout: 5m
elasticSecurityAlert:
name: "S3 Public Access Block Disabled"Swap detonate for inject to test a rule without running an attack, or add a collect block to capture the raw logs the attack produced.
β Scenarios reference.
Prerequisites: mise (manages Go 1.25 and Node 22), PostgreSQL.
# Build the frontend + binary β dist/simrun
mise run build
# Point it at Postgres and run
export SR_DATABASE_URL="postgres://user:pass@localhost:5432/simrun?sslmode=disable"
./dist/simrun # serves UI + API on http://localhost:8080Schema migrations run automatically on startup. Authentication is optional β without Google OAuth credentials, SimRun runs unauthenticated.
β Then follow the Walkthrough to run your first detection test.
The Coverage view (/rules/coverage) pulls every detection rule from your Elastic deployment and answers the question CI never could: which of these rules does a SimRun scenario actually exercise, and did it pass last time? Rules with no scenario are flagged as blind spots; the summary reports an overall covered-rules percentage.
Simulations are distributed as packs β versioned bundles of Terraform modules, scenario definitions, and a manifest. Two first-party packs are maintained alongside SimRun:
| Pack | What it is |
|---|---|
| simrun-pack | The reference pack and a worked example of authoring simulations in Go (AWS, Kubernetes, Okta injections). |
| simrun-stratus-adapter | Plug-and-play wrapper that exposes the entire Stratus Red Team technique registry as a SimRun pack. |
β Ecosystem & authoring guide.
- Getting Started β prerequisites, build, first run
- Concepts β assessments, runs, detonators, matchers, collectors
- Walkthrough β end-to-end tutorial
- Scenarios β YAML schema reference
- Connectors & Secrets β SIEM and cloud integrations
- Packs β install and configure simulation packs
- Ecosystem β the pack ecosystem and writing your own
- Configuration β environment variables reference
- Deployment β Docker, production notes, OAuth setup
mise run build-frontend # build just the SvelteKit frontend
go test ./... # run the test suite
mise run lint # run golangci-lint
go generate ./... # regenerate mocks (mockery)
mise run parser # regenerate parser from JSON schemasSimRun stands on excellent prior work in the detection-engineering community:
- Threatest by Datadog pioneered the detonate-and-verify model for detection testing and shaped how we think about correlating attacks to alerts.
- Stratus Red Team, also by Datadog, provides the MITRE ATT&CKβmapped cloud attack techniques that SimRun exposes through simrun-stratus-adapter.
Issues and pull requests are welcome.
Licensed under the Apache License 2.0. See LICENSE.