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.sarifto generate machine-readable scan results. - Python API: The
graph.invoke()method accepts anoutput_formatparameter, returning SARIF data as a dictionary via thesarif_reportkey. - 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), andsrc/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →