For the complete documentation index, see llms.txt. This page is also available as Markdown.

CLI

Scanner provides a Python CLI for validating, testing, and syncing detection rule YAML files. The package is published as scanner-cli on PyPI.

Installation

We recommend installing scanner-cli with pipx, which puts the CLI in its own isolated virtual environment and on your PATH:

pipx install scanner-cli

Installing pipx

If you don't already have pipx, install it via one of the following.

brew install pipx
pipx ensurepath

Restart your shell after pipx ensurepath so the updated PATH takes effect. See the pipx installation docs for additional platforms.

Authentication

You will need the API URL of your Scanner instance and an API key. Find both under Settings > API Keys.

Either export them as environment variables:

export SCANNER_API_URL=<Scanner API URL>
export SCANNER_API_KEY=<Scanner API key>

or pass them on every invocation:

Validate detection rule

To validate files:

To validate directories:

Only YAML files with the correct schema header will be validated. Multiple files or directories can be provided. To recursively search through directories, use the recursive flag -r.

validate checks that the specified files are valid Scanner detection rule files. After validating files, use run-teststo check that all tests pass before syncing to Scanner.

Example

Validate detection rules

Run detection rule tests

To run detection rule tests on files:

To run detection rule tests on directories:

This will only run tests on YAML files with the correct schema header. Multiple files or directories can be provided. To recursively search through directories, use the recursive flag -r.

Example

Run tests

Sync an entire repository (sync-git-repo)

sync-git-repo is the CLI implementation of user-pushed sync. It uploads the tracked files in a Git working tree (via git ls-files) to a push sync source on Scanner by calling POST /v1/upload_git_repo_zipball. The server runs the same validate / test / materialize pipeline as a GitHub-polled sync, so a successful upload is equivalent to a poll-mode sync cycle — including deleting rules whose YAML has been removed from the repository.

If your rules are on GitHub.com or GitHub Enterprise Server, the scanner-inc/sync-detection-rules GitHub Action wraps this command and surfaces failures as PR annotations. See getting-started.md → user-pushed sync. The notes below describe the underlying scanner-cli command.

To run a sync from the current directory:

To sync a different working tree, pass it as a positional argument:

<push-key> identifies the push sync source on Scanner — find or create one under Detections > Synced Repositories. The current branch (the working tree must not be in a detached-HEAD state), commit SHA, and HEAD commit message (git log -1 --pretty=%B) are derived from the repo and sent with the upload; a dirty working tree is allowed and reported with a +dirty suffix on the commit SHA. There's no --branch flag — the branch is always the one currently checked out, and the upload targets the sync source whose (push_key, branch) matches. If no source is registered for the current branch, the upload is rejected.

If any rule in the upload fails to validate or its tests fail, the server rejects the whole upload — no rules from it are synced. The CLI prints the per-file failures so you can fix them and re-run.

Sync individual rules (sync)

-f, -d <dir>, and -r (recursive) work the same way as validate and run-tests. --team-id is the Scanner team to sync into (see Settings > General). --sync-config-file points at a YAML file containing the event_sink_keys → event_sink_ids mapping that resolves any event_sink_keys referenced by your rules; pass an empty file if your rules don't use event-sink keys.

Each rule's YAML must include a push_key field at the top level — that field is the per-rule identifier the server uses to look up an existing detection rule to update (or create a new one if none matches). See the detection rule schema for the field's exact placement.

Failing tests

Tests fail if:

  • The expected_detection_resultis true and the provided log events do not trigger a detection in the specified time window

  • The expected_detection_resultis false and the provided log events trigger a detection in the specified time window

Tips for debugging failed tests:

  • Check that the log events are hits for query_text

  • Check that the log events have timestamps that fall in the time window specified by now_timestamp, time_range_s , and run_frequency_s

    • If now_timestampis not provided, the timestamp of the latest log event is used. In both cases, the timestamps are rounded to the next run_frequency_s.

    • Example: if time_range_sis 600 seconds, run_frequency_sis 60 seconds, and now_timestampis 2024-07-05T10:15:00.000Z, the time window specified is 2024-07-05T10:05:00.000Z to 2024-07-05T10:15:00.000Z. Log events must have timestamps in this time window in order to trigger an alert.

Last updated

Was this helpful?