Skip to content

IBM/simrun

Repository files navigation

SimRun

SimRun

An Attack Simulation Platform for detection engineering.
Detonate attacks, verify the alerts fire, and measure exactly which detections you're testing β€” across multiple clouds.

License Release Go Docker


Why SimRun

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.

How it works

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
Loading

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.

A scenario, end to end

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.

Quickstart (60 seconds)

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:8080

Schema 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.

Rule Coverage

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.

The pack ecosystem

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.

Documentation

Development

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 schemas

Acknowledgments

SimRun 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.

Contributing

Issues and pull requests are welcome.

License

Licensed under the Apache License 2.0. See LICENSE.