Hamburger Cross Icon
Max Severity
+
CodeQL Collector

Max Severity + CodeQL Collector

Guardrail Collector Stable Security And Compliance

Enforce Max Severity using data collected by CodeQL Collector. Automatically check security and compliance standards on every PR.

Guardrail: Ensures no findings at or above the configured severity threshold. Configure min_severity to set the threshold (critical, high, medium, low).
Data Source: Detects GitHub CodeQL security scanning via GitHub Code Scanning check-runs or CLI integration in CI pipelines. Writes to normalized SAST Component JSON paths, enabling tool-agnostic SAST policies.

How CodeQL Collector Powers This Guardrail

The CodeQL Collector gathers metadata from your systems. This data flows into Lunar's Component JSON, where the Max Severity guardrail evaluates it against your standards.

When enabled, this check runs automatically on every PR and in AI coding workflows, providing real-time enforcement with actionable feedback.

1
CodeQL Collector Gathers Data Collector
Extracts metadata from code, configs, and tool outputs
2
{ } Component JSON
Data centralized in structured format for evaluation
3
Max Severity Checks Guardrail
Pass/fail result with actionable feedback in PRs

Quick Start Configuration

Add both the collector and policy to your lunar-config.yml to enable this guardrail.

📄 lunar-config.yml
# Step 1: Enable the CodeQL Collector
collectors:
  - uses: github://earthly/lunar-lib/collectors/codeql@v1.0.5
    # with: ...

# Step 2: Enable the SAST Guardrails
policies:
  - uses: github://earthly/lunar-lib/policies/sast@v1.0.5
    include: [max-severity]
    # with: ...

What CodeQL Collector Collects

This collector gathers the following data that the Max Severity guardrail evaluates.

Collector code

github-app

Detects CodeQL scans on pull requests by querying GitHub check-runs API for the github-advanced-security app. Waits for scan completion and captures check status, conclusion, and URLs.

Collector code

running-in-prs

Proves CodeQL is running on PRs by querying Lunar Hub for CodeQL data from recent PRs. Used on the default branch to provide compliance proof that PR scanning is happening.

Collector

cicd

Detects CodeQL CLI or legacy codeql-runner executions in CI pipelines. Captures command metadata and, when the SARIF output file is available on disk (from codeql database analyze/interpret-results), collects the raw SARIF and normalizes findings into .sast.findings and .sast.issues.

Collector after-json

monorepo-fanout

Redistributes a monorepo's repo-wide CodeQL findings to its subdirectory components, so each one gets the findings under its own paths instead of reading as unscanned.

ONLY for monorepos, and target it at the repository ROOT — the component whose name is the repo itself. Point it at anything else and it does useless work on every commit: a component with no subcomponents has nothing to fan out. Scope it with on: ["component:<repo>"], not a broad domain selector.

Enable alongside cicd on that root: cicd writes the findings, this distributes them. A finding reaches a subcomponent when its file matches that subcomponent's paths: (plus the implicit "/*"), the same rule the Hub uses for change detection. .sast.native stays on the root; subcomponents get the severity counts their policies read plus provenance under .sast.source.fanout. One that already has its own SAST scan is never overwritten.

Requires Hub v3.3.0+. The root also needs at least one policy — an after-json collector is dispatched by the doneness gate, which is only consulted while bundling a component's policies.

Example Data Flow

Here's an example of the data that CodeQL Collector writes to the Component JSON, which Max Severity then evaluates.

{ } component.json From CodeQL Collector
{
  "sast": {
    "running_in_prs": true,
    "source": {
      "tool": "codeql",
      "version": "2.16.0",
      "integration": "ci"
    },
    "findings": {
      "critical": 0,
      "high": 1,
      "medium": 3,
      "low": 0,
      "total": 4
    },
    "issues": [
      {
        "severity": "high",
        "rule": "go/sql-injection",
        "file": "db/query.go",
        "line": 42,
        "message": "Unsanitized input used in SQL query"
      }
    ],
    "summary": {
      "has_critical": false,
      "has_high": true
    },
    "native": {
      "codeql": {
        "github_app": {
          "id": 12345,
          "name": "CodeQL",
          "status": "completed",
          "conclusion": "success"
        },
        "cicd": {
          "cmds": [
            {"cmd": "codeql database interpret-results --format=sarif-latest --output=../results/go.sarif", "version": "2.16.0"}
          ]
        },
        "sarif": {}
      }
    }
  }
}

Configuration Options

CodeQL Collector Inputs

Input Required Default Description
monorepo_fanout_include_issues Optional false Also write the per-finding array (`.sast.issues`) to each subcomponent, sliced to the findings that component owns. Off by default: `policies/sast` reads `.sast.summary.has_<sev>` and `.sast.findings.<sev>`, and `max-total` reads `.sast.findings.total` — none of them read `.sast.issues`, so shipping it multiplies write size by findings x subcomponents for data no guardrail evaluates. Turn it on if you want the per-finding detail visible on each service in the UI.

SAST Guardrails Inputs

Input Required Default Description
min_severity Optional high Minimum severity to fail on (critical, high, medium, low)
max_total_threshold Required Maximum total findings allowed (must be configured)

Ready to Automate Your Standards?

See how Lunar can turn your AGENTS.md, engineering wiki, compliance docs, or postmortem action items into automated guardrails with our 200+ built-in guardrails.

Works with any process
check AI agent rules & prompt files
check Post-mortem action items
check Security & compliance policies
check Testing & quality requirements
Automate Now
Paste your AGENTS.md or manual process doc and get guardrails in minutes
Book a Demo