HackBlue

Tools · Network IDS and detection as code · 04 / 04

Detection as code: lint and convert a Sigma rules repository in CI

Run sigma check and a conversion step on every pull request to a detection repository, so broken YAML, missing fields, and rules that no longer convert are caught before they reach the SIEM.

11 min read · practice only with authorization

Treat detections like code

A detection edited in a SIEM console has no review, no history, and no test. Keeping Sigma rules in git gives all three. The CI job is what makes the repository trustworthy: a rule that does not parse or convert never merges.

sigma check

sigma check parses every rule and reports errors and validator warnings: duplicate IDs, missing required fields, wildcards that make a condition match everything, and more. Errors fail the step.

Snippet
sigma check rules/

Found 0 errors, 0 condition errors and 2 issues.
Validation issue summary:
+-------+------------------------------+----------+----------------------------------+
| Count | Issue                        | Severity | Details                          |
+-------+------------------------------+----------+----------------------------------+
| 1     | IdentifierExistenceIssue     | medium   | Rule has no identifier (UUID)    |
| 1     | DuplicateTitleIssue          | medium   | Rule title used by multiple rules|
+-------+------------------------------+----------+----------------------------------+

The workflow

This GitHub Actions job lints the rules, converts them for the production backend with the same pipelines the deploy step uses, and stores the generated queries as an artifact for reviewers. A rule the backend cannot convert makes sigma convert exit non-zero, which fails the job.

Snippet
name: detections
on: [pull_request]
jobs:
  sigma:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install sigma-cli && sigma plugin install splunk
      - run: sigma check rules/
      - run: sigma convert -t splunk -p splunk_windows -p pipelines/lab_splunk_fields.yml rules/ -o build/queries.spl
      - uses: actions/upload-artifact@v4
        with: { name: queries, path: build/queries.spl }

Worked review of a pull request

An analyst adds a rule for new local administrator accounts. CI fails: the rule reuses an ID copied from an existing rule. The analyst generates a new UUID, CI passes, and the reviewer reads the converted SPL in the artifact rather than guessing what the YAML will become. The reviewer also asks for a test event in tests/, a sample log line that should match, so the next change can be checked against it.

Diagram

What each CI stage catches

Each stage stops a different class of mistake.

  • sigma check

    Broken YAML, missing IDs, duplicate titles, risky wildcards.

  • sigma convert

    Rules that the production backend or pipeline cannot express.

  • Artifact

    Lets reviewers read the exact query that will be deployed.

  • Test events

    Sample log lines that each rule must still match.

Check yourself

1. What does sigma check report?

2. Why upload the converted queries as a CI artifact?

3. A new rule copied another rule’s id. What should happen?