How to Integrate NVIDIA SkillSpector into CI/CD Pipelines Using SARIF Output

You can integrate SkillSpector into CI/CD pipelines by invoking skillspector scan --format sarif to generate a SARIF 2.1.0 file, then uploading that report to your platform's code scanning service to automatically annotate pull requests with security findings.

NVIDIA SkillSpector is a specialized static analysis tool designed for evaluating AI skill definitions and code patterns. When you integrate SkillSpector into CI/CD pipelines using SARIF output, you enable automated security scanning that feeds directly into native code scanning dashboards, allowing teams to catch vulnerabilities before they reach production.

Understanding SkillSpector's SARIF Architecture

SkillSpector's reporting pipeline is built around a report node that produces a SARIF 2.1.0 document. This standardized format allows CI/CD systems including GitHub Actions, Azure Pipelines, and GitLab CI to ingest findings directly without custom parsing logic.

From CLI Arguments to Graph State

The integration begins in src/skillspector/cli.py where the skillspector scan command parses the --format flag. When the value is sarif, the CLI stores "output_format": "sarif" in the initial graph state within the _scan_state dictionary (lines 95-101). This state object persists through the LangGraph workflow execution.

The graph.invoke() method orchestrates a series of analyzer nodes—including static pattern matchers, optional LLM semantic checks, and OSV lookups—that collect findings into the filtered_findings state field.

SARIF Generation in the Report Node

The report node in src/skillspector/nodes/report.py (lines 48-66) handles the actual transformation. The report() function reads the accumulated findings and calls _build_sarif, which iterates over each Finding object and creates a SarifResult containing:

  • Rule ID mapping to the specific vulnerability pattern
  • Message describing the finding
  • Severity level mapped to SARIF's standardized levels
  • File location with precise line and column ranges

The _build_sarif function assembles a SarifLog object using the Pydantic models defined in src/skillspector/sarif_models.py, then serializes it to a plain Python dictionary via model_dump(..., by_alias=True).

Output Handling and Persistence

In the CLI's _write_result helper (cli.py), when the selected format is SARIF, the report_body contains the raw SARIF dictionary. The CLI writes this as a pretty-printed JSON file using json.dumps(..., indent=2), ensuring the output is human-readable while remaining machine-parseable.

CI/CD Integration Examples

Because the SARIF payload is a plain JSON object, it integrates seamlessly with major CI/CD platforms. Each platform can ingest the report.sarif file to create security dashboards and block merges based on detected risk.

GitHub Actions with Code Scanning

GitHub's Code Scanning API natively understands SARIF 2.1.0. Use the github/codeql-action/upload-sarif action to automatically create alerts from your SkillSpector findings.

name: SkillSpector CI
on: [push, pull_request]

jobs:
  scan-skill:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install SkillSpector
        run: |
          python -m pip install --upgrade pip
          pip install skillspector[all]

      - name: Run SkillSpector (SARIF)
        id: scan
        run: |
          skillspector scan . \
            --format sarif \
            --output skill_report.sarif

      - name: Upload SARIF report
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: skill_report.sarif

The upload-sarif action automatically creates Code Scanning alerts visible in the Security tab and annotates pull request files with inline comments.

Azure Pipelines Configuration

Azure DevOps can publish SARIF files as test results using the PublishTestResults@2 task with the SARIF format.

trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

steps:
- script: |
    python -m pip install --upgrade pip
    pip install skillspector[all]
  displayName: 'Install SkillSpector'

- script: |
    skillspector scan $(Build.SourcesDirectory) \
      --format sarif \
      --output $(Build.ArtifactStagingDirectory)/skill.sarif
  displayName: 'Run SkillSpector'

- task: PublishTestResults@2
  inputs:
    testResultsFormat: 'SARIF'
    testResultsFiles: '$(Build.ArtifactStagingDirectory)/skill.sarif'
    mergeTestResults: true

GitLab CI Security Reports

GitLab's Security Reports UI renders SARIF findings automatically when you specify the sarif report type in your job artifacts.

stages:
  - scan

skill_scan:
  image: python:3.12-slim
  stage: scan
  script:
    - pip install skillspector[all]
    - skillspector scan $CI_PROJECT_DIR --format sarif --output skill.sarif
  artifacts:
    paths:
      - skill.sarif
    reports:
      sarif: skill.sarif

Programmatic Integration via Python API

For custom pipeline scripts, invoke SkillSpector directly through its Python API without shelling out to the CLI.

from skillspector import graph
import json
import pathlib

# Build the initial state with SARIF output format

state = {
    "input_path": "/path/to/skill",
    "output_format": "sarif",
    "use_llm": False,  # Static-only for faster CI execution

}

# Execute the full analysis workflow

result = graph.invoke(state)

# Extract the SARIF document as a dictionary

sarif_report = result["sarif_report"]

# Write to file for downstream CI consumption

path = pathlib.Path("skill_report.sarif")
path.write_text(json.dumps(sarif_report, indent=2))
print(f"SARIF saved to {path}")

Configuring Pipeline Failures and Risk Thresholds

SkillSpector supports deterministic pipeline gating through exit codes. According to the source implementation in cli.py, the scanner exits with a non-zero status when the aggregated risk_score exceeds 50, allowing you to fail builds automatically based on severity thresholds.

You can also parse the SARIF output programmatically to implement custom logic. The SARIF log contains a top-level runs array with a single run, a tool.driver entry identifying SkillSpector, and a results list where each entry maps to a specific finding with its severity level.

Summary

  • SARIF 2.1.0 Standard: SkillSpector generates standardized SARIF output via src/skillspector/nodes/report.py, enabling direct integration with GitHub, Azure, and GitLab security dashboards.
  • CLI Integration: Use skillspector scan --format sarif --output report.sarif to generate machine-readable scan results.
  • Python API: The graph.invoke() method accepts an output_format parameter, returning SARIF data as a dictionary via the sarif_report key.
  • Pipeline Gating: The tool exits with non-zero status when risk_score > 50, enabling automatic build failure for high-risk findings.
  • Source References: Key files include src/skillspector/cli.py (CLI handling), src/skillspector/nodes/report.py (SARIF construction), and src/skillspector/sarif_models.py (Pydantic schema definitions).

Frequently Asked Questions

What is SARIF and why does SkillSpector use it?

SARIF (Static Analysis Results Interchange Format) is an OASIS standard JSON schema designed for static analysis tools. SkillSpector uses SARIF 2.1.0 because it provides a standardized way to represent findings with precise file locations, severity levels, and rule metadata. This allows CI/CD platforms like GitHub and GitLab to ingest results natively without requiring custom parsers or adapters.

How do I fail a CI pipeline based on SkillSpector findings?

SkillSpector automatically exits with a non-zero status code when the aggregate risk_score exceeds 50, which fails the CI job immediately. For custom thresholds, parse the generated SARIF file and inspect the results array. Each result contains a level property (error, warning, note) that you can evaluate against your organization's quality gates using a simple script in your pipeline.

Can I use SkillSpector without installing Python in my CI environment?

Currently, SkillSpector requires Python 3.12 or later to run. You must install it via pip install skillspector[all] in your CI environment. The [all] extra includes dependencies necessary for full SARIF generation and LLM integration. Container-based CI jobs can use the python:3.12-slim image or a custom image with SkillSpector pre-installed to avoid repeated installations.

Where are the SARIF Pydantic models defined in the source code?

The SARIF schema definitions are located in src/skillspector/sarif_models.py. This file contains Pydantic models for SarifLog, SarifRun, SarifResult, and related structures that validate the output against the SARIF 2.1.0 specification. The report() node in src/skillspector/nodes/report.py uses these models to construct the final document before serialization.

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 →