Security scanning

Stategraph scans your infrastructure with checkov in Infrastructure as a Database, and can run it in a Stategraph Orchestration workflow step. With the step, a pull request fails or waits for approval when the plan adds a misconfiguration.

Scanning in Infrastructure as a Database

Stategraph runs two types of scan:

  • A current scan of the HCL of each state, on a schedule.
  • A planned scan of the planned change of each transaction, at plan time.

A finding has the checkov check ID, the resource address, and an effective severity: the scanner's severity adjusted for context, for example raised for a resource reachable from the internet.

On a self-hosted server, scanning is off by default: see Enable security scanning. Where scanning is disabled, the security commands say so instead of failing.

Findings in the plan

After the diff, stategraph tf plan prints the security impact of the change. The impact is the findings that the change adds and resolves, compared with the latest current scan of each affected state. The plan waits up to three seconds for it. Change the wait with --security-wait or STATEGRAPH_SECURITY_WAIT_SECONDS, or skip it with --skip-security.

If the impact is not ready in time, the plan points to the impact commands. Get it later with the transaction ID:

stategraph security impact summary --tx <tx-id>

Output:

metric                        value
----------------------------  --------------------
source                        planned
computed_at                   2026-09-10T12:47:32Z
states_affected               1
cross_boundary_finding_count  0
added:critical                0
added:high                    1
added:medium                  0
added:low                     0
added:info                    0
added:unknown                 0
resolved:critical             0
resolved:high                 0
resolved:medium               2
resolved:low                  0
resolved:info                 0
resolved:unknown              0

stategraph security impact findings --tx <tx-id> prints the added and resolved findings as JSON. While the computation runs, both commands report that the impact is not ready yet.

Current findings for a state

Get the severity rollup and top failing checks for a state's latest current scan:

stategraph security findings summary --state <state-id>

List the findings, optionally by severity:

stategraph security findings list --state <state-id> --severity high

Each row has the check ID, effective severity, resource address, number of resources in the blast radius of the finding, and a fingerprint. --format json returns the full finding objects.

stategraph security scans list --state <state-id> shows the scan history. stategraph security scan --state <state-id> queues a new scan in the background. Run the summary again when it completes.

Posture over time

Track the tenant's security posture day by day:

stategraph security history --tenant <tenant-id> --from 2026-08-01T00:00:00Z

The table has one row per day, with the total and the count per severity, for the last 30 days by default. In the console, the Overview screen under Security charts the same history for all states of the tenant.

Checkov in the pull request

To run checkov against the generated plan, add the checkov step after plan in .stategraph/config.yml:

workflows:
  - tag_query: ''
    plan:
      - type: init
      - type: plan
      - type: checkov

With the step:

  1. The checkov step scans the plan file from init and plan for misconfigurations and policy violations.
  2. If checkov finds issues, it exits non-zero and the plan fails.
  3. The plan results on the pull request include the checkov output, with details of each finding.
  4. If the scan is clean, the plan succeeds, and you review and apply it as usual.
Stategraph GitHub AppbotAccess token usercommented
Plans ✖️

Running plans FAILED. See Stategraph Plan Output.

After resolving the issue, run stategraph plan to execute the plan operation again.

Stategraph Plan Output ✖️
Expand for plan output details
edge | default | ✖️
Dir: edge
Workspace: default
Success: ✖️
Step: tf/plan
Success: 👍
Terraform will perform the following actions:

  # google_compute_security_policy.policy will be created
  + resource "google_compute_security_policy" "policy" {
      + id   = (known after apply)
      + name = "edge-policy"
      ...
    }

Plan: 1 to add, 0 to change, 0 to destroy.
Step: tf/checkov
Success: ✖️
Command: checkov --quiet --compact -f /tmp/tmp7k2m9d/checkov.plan.json
terraform_plan scan results:

Passed checks: 0, Failed checks: 1, Skipped checks: 0

Check: CKV_GCP_73: "Ensure Cloud Armor prevents message lookup in Log4j2. See CVE-2021-44228 aka log4jshell"
    FAILED for resource: google_compute_security_policy.policy
    File: /checkov.plan.json:0-0

Feedback?

Questions? Comments? Give feedback by commenting stategraph feedback <your msg>. Your message lands directly in our inbox.

A plan that failed the checkov scan.
The tf/checkov step lists each failed check and resource.

Approval gates

  • Set gate on the checkov step to record a gate instead of failing the plan. Orchestration then blocks the apply until an authorized user approves it. See Gatekeeper.
  • Set ignore_errors: true to report findings without blocking.

The workflows reference lists all keys of the step, including extra_args, env, run_on, and visible_on.

Checkov version

To use a specific checkov release, set CHECKOV_VERSION before the step:

workflows:
  - tag_query: ''
    plan:
      - type: env
        name: CHECKOV_VERSION
        cmd: ['echo', '2.3.123']
      - type: init
      - type: plan
      - type: checkov

Otherwise, the runner uses the version installed in its environment.

Skip checks

Checkov reads its options from environment variables. Set CKV_SKIP_CHECK to a comma-separated list of check IDs to skip:

workflows:
  - tag_query: ''
    plan:
      - type: env
        name: CKV_SKIP_CHECK
        cmd: ['echo', 'CKV_GCP_73']
      - type: init
      - type: plan
      - type: checkov

CKV_CHECK limits the scan to specific check IDs. The checkov CLI reference lists all options.

Next steps