How dcg's SARIF Output Works for CI Integration

The dcg (destructive_command_guard) CLI generates SARIF 2.1.0-compliant JSON through src/sarif.rs, converting scan findings into structured results that CI platforms like GitHub Actions, GitLab CI, and Azure DevOps can ingest natively for security reporting.

The dcg tool analyzes shell scripts and configuration files for potentially destructive commands. When integrated into continuous integration pipelines, it outputs findings using the Static Analysis Results Interchange Format (SARIF), enabling automated security scanning with rich metadata about detected risks. The implementation follows the official SARIF 2.1.0 schema to ensure compatibility across modern DevOps platforms.

Understanding the SARIF 2.1.0 Implementation

The SARIF module (src/sarif.rs) implements a complete serialization layer that transforms the internal ScanReport structure into a standards-compliant JSON document. This conversion happens through SarifReport::from_scan_report, which constructs the hierarchical object model required by the specification.

Tool Metadata and Run Configuration

The generated report begins with schema-level metadata including the $schema URI (SARIF_SCHEMA) and version identifier (SARIF_VERSION). The implementation creates a single SarifRun object containing:

  • Tool metadata (SarifTool → SarifToolComponent) populated with the dcg name, version, and a link back to the repository via DCG_INFO_URI【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L26-L38】
  • Invocation details that record the working directory and mark the execution as successful【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L40-L52】

Rule Aggregation and Descriptor Mapping

Before emitting results, the code aggregates unique rule definitions to avoid duplication. While iterating over ScanFindings, it builds a deduplicated map of SarifReportingDescriptor objects. Each descriptor includes:

  • A human-readable name generated via humanize_rule_id
  • Short description text
  • A help URL pointing to the rule's markdown documentation in the repository
  • Default severity and enablement settings【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L90-L107】

Converting Findings to SARIF Results

The finding_to_result function maps each finding to a SarifResult object, excluding only those with an Allow decision. The conversion process:

  1. Severity mapping: Translates internal decisions to SARIF levels—Deny becomes Error, Warn becomes Warning, and Allow becomes Note (implemented in From<ScanSeverity>)【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L47-L57】【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L64-L68】
  2. Location embedding: Creates a SarifLocation containing the file URI, precise line/column coordinates, and a snippet of the extracted command【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L82-L99】
  3. Suggestion handling: Adds a SarifFix with textual description when remediation advice is available【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L102-L108】
  4. Metadata preservation: Stores extractor ID, command text, and decision data in a SarifPropertyBag for downstream tooling【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L77-L81】

Filtering and Severity Mapping

The implementation filters findings to maintain focus on actionable issues. Only findings with Deny or Warn decisions are emitted to the final SARIF document; Allow results are intentionally omitted to reduce noise in CI reports【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L23-L25】.

This severity mapping ensures that:

  • Blocking issues (Deny) appear as errors in CI dashboards
  • Advisory issues (Warn) surface as warnings
  • Permitted patterns (Allow) do not clutter the security report

CLI Integration and Output Generation

When executing dcg scan --output sarif, the CLI invokes the serialization pipeline documented in src/main.rs. The scan subcommand processes the --output flag to determine the format, calling SarifReport::from_scan_report and serializing the structure using serde_json::to_string_pretty【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/main.rs#L1155-L1159】.

The resulting JSON writes to stdout or a specified file:

// Simplified from the scan command implementation
let report = scanner.run(&paths)?;
let sarif = crate::sarif::SarifReport::from_scan_report(&report);
let json = serde_json::to_string_pretty(&sarif)?;
println!("{}", json);

For file output, redirect the stream or use the appropriate shell redirection:

dcg scan . --output sarif > security-report.sarif

CI/CD Platform Integration

Because the output conforms to the SARIF 2.1.0 specification, major CI platforms can consume the results without custom parsers.

GitHub Actions

GitHub's upload-sarif action ingests the JSON directly into the Code scanning dashboard. The workflow step requires only the file path:

- name: Run destructive command scan
  run: dcg scan . --output sarif > dcg-results.sarif

- name: Upload SARIF to GitHub
  uses: github/codeql-action/upload-sarif@v2
  with:
    sarif_file: dcg-results.sarif

GitLab CI

GitLab's codequality report type accepts SARIF format, displaying findings in merge request pipelines:

security_scan:
  script:
    - dcg scan . --output sarif > gl-code-quality-report.json
  artifacts:
    reports:
      codequality: gl-code-quality-report.json

Azure DevOps

Azure DevOps automatically parses SARIF files in the Security tab when published as build artifacts. Use the Publish Build Artifacts task to make the report available to the built-in security analysis tools.

Summary

  • SARIF 2.1.0 compliance: The src/sarif.rs module implements the full specification with schema validation, tool metadata, and run invocations
  • Structured conversion: SarifReport::from_scan_report transforms internal ScanReport objects into standardized JSON with preserved location data and fix suggestions
  • Severity translation: Internal decisions map directly to SARIF levels—Deny → Error, Warn → Warning—while Allow findings are filtered from output
  • Universal CI support: Native integration with GitHub Actions, GitLab CI, and Azure DevOps through standard SARIF ingestion APIs
  • Rich metadata: Each result includes command snippets, file locations, rule documentation URLs, and property bags for extensibility

Frequently Asked Questions

How does dcg handle false positives in SARIF output?

Findings marked with an Allow decision are filtered out during the SARIF generation process in src/sarif.rs【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L23-L25】. This ensures that explicitly permitted patterns do not appear in CI security dashboards, keeping the report focused on actionable violations.

Can I customize the severity levels in the SARIF output?

The severity levels are determined by the rule's decision type (Deny, Warn, or Allow) and mapped to SARIF levels through the From<ScanSeverity> implementation【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L47-L57】. While the CLI does not expose direct severity customization flags, you can modify rule configurations to change whether a pattern triggers a Deny or Warn decision, which indirectly affects the SARIF level.

What information is included in the SARIF property bag?

The SarifPropertyBag contains additional metadata for each finding, including the extractor ID that identified the command, the full command text, and the specific decision rendered【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/sarif.rs#L77-L81】. This data enables downstream tools to perform custom filtering or correlation without parsing the formatted message strings.

Does dcg support SARIF output for all scan commands?

The SARIF output is specifically implemented for the scan subcommand via the --output sarif flag, as documented in src/main.rs【/cache/repos/github.com/Dicklesworthstone/destructive_command_guard/main/src/main.rs#L1155-L1159】. When invoked, the CLI routes the ScanReport through the sarif module serializer, producing JSON that can be consumed by any SARIF-compatible platform.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →