How to Integrate SkillSpector into a CI/CD Pipeline for Automated Security Scanning
Integrate SkillSpector into your CI/CD pipeline by installing the Python package, running skillspector scan with SARIF output format, and uploading the resulting .sarif file to your platform's security dashboard.
SkillSpector is an open-source security scanner developed by NVIDIA that analyzes AI-agent skill packages—including SKILL.md files, source code, and dependencies—to generate risk scores and remediation guidance. Adding automated security scans to your continuous integration workflow ensures that every commit is validated against vulnerability patterns before deployment.
Understanding SkillSpector's Architecture for CI/CD Integration
SkillSpector is built around a LangGraph workflow that orchestrates two distinct analysis stages. According to the NVIDIA/SkillSpector source code, this design enables flexible execution modes suitable for fast CI checks and comprehensive security audits.
Core Components
The integration relies on three primary source files:
src/skillspector/cli.py– Parses command-line arguments, constructs the initial graph state, and handles report serialization including SARIF generation.src/skillspector/graph.py– Instantiates the LangGraph workflow, executes static and optional LLM analysis nodes, and returns a dictionary containingreport_bodyandsarif_report.src/skillspector/sarif_models.py– Implements the SARIF 2.1 schema, converting internal findings into the standardized JSON format that CI platforms consume.
Additional supporting modules include src/skillspector/providers/ (LLM adapters for OpenAI, Anthropic, and NVIDIA) and src/skillspector/constants.py (risk-scoring thresholds and pattern definitions).
The Two-Stage Analysis Workflow
SkillSpector executes security checks through two sequential stages:
- Static Analysis – Fast regex-driven pattern matching, AST inspection, and live OSV vulnerability lookups. This stage is deterministic, requires no external API calls (except OSV lookups), and completes in seconds.
- Optional LLM Semantic Analysis – A language-model validation step that reviews static findings to reduce false positives. Enabled when
--no-llmis omitted and provider credentials are configured via environment variables (SKILLSPECTOR_PROVIDER,OPENAI_API_KEY, etc.).
Both stages populate a unified result object that the CLI formats into terminal, JSON, Markdown, or SARIF output.
Generating SARIF Reports for CI Platforms
SARIF (Static Analysis Results Interchange Format) is the standard exchange format for static analysis tools. SkillSpector emits a multi-run SARIF document where the first run contains static findings and a second run (when LLM analysis is enabled) contains dynamic findings. This structure allows security dashboards to display provenance information for each vulnerability.
To generate SARIF output, use the -f or --format flag combined with an output file:
skillspector scan . -f sarif -o report.sarif --no-llm
The resulting file adheres to the SARIF 2.1 schema and can be consumed directly by GitHub Advanced Security, GitLab SAST dashboards, Azure DevOps security reports, and other SARIF-compatible platforms.
Step-by-Step CI/CD Integration
1. Install SkillSpector
Install the package via pip or use a container image. For Python-based workflows:
pip install skillspector
For Docker-based workflows, build from the repository or use a pre-built image mounting your source code as a volume.
2. Execute the Security Scan
Run the scan against your skill package directory. For CI environments, use static-only mode (--no-llm) to ensure fast, deterministic results without external API dependencies:
skillspector scan ./my-skill -f sarif -o report.sarif --no-llm
If your pipeline requires deeper semantic analysis, omit --no-llm and ensure the appropriate provider API key is available via environment variables.
3. Upload SARIF to Your Platform
Upload the generated report.sarif to your CI platform's security reporting service:
- GitHub Actions: Use
github/codeql-action/upload-sarifor the nativeupload-sarifaction. - GitLab CI: Configure
artifacts:reports:sastin your job definition. - Azure Pipelines: Use the
PublishSecurityAnalysisLogs@3task.
CI/CD Implementation Examples
GitHub Actions Workflow (Static Only)
This workflow triggers on commits affecting skill files, runs a static-only scan, and uploads results to GitHub Code Scanning:
name: SkillSpector Security Scan
on:
push:
paths:
- '**.md'
- '**.py'
- '**/requirements.txt'
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
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
- name: Run static scan and generate SARIF
run: |
skillspector scan . -f sarif -o report.sarif --no-llm
- name: Upload SARIF to GitHub Code Scanning
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: report.sarif
GitLab CI Configuration (Conditional LLM)
This example conditionally enables LLM analysis if the ANTHROPIC_API_KEY variable is present, otherwise falling back to static-only mode:
skillsspector_scan:
image: python:3.12-slim
stage: test
script:
- pip install --no-cache-dir skillspector
- |
if [ -n "$ANTHROPIC_API_KEY" ]; then
export SKILLSPECTOR_PROVIDER=anthropic
skillspector scan . -f sarif -o report.sarif
else
skillspector scan . -f sarif -o report.sarif --no-llm
fi
artifacts:
reports:
sast: report.sarif
expire_in: 1 week
Python API Integration
For custom CI scripts, invoke the LangGraph workflow directly via the Python API:
from skillspector.graph import graph
import json
result = graph.invoke({
"input_path": "./my-skill",
"output_format": "sarif",
"use_llm": False, # Static-only for CI speed
})
# Write the SARIF payload to a file for upload
with open("report.sarif", "w", encoding="utf-8") as f:
json.dump(result["sarif_report"], f, indent=2)
Docker-Based Scanning
Run SkillSpector without installing Python on the host runner:
docker build -t skillspector .
docker run --rm \
-v "$(pwd)":/scan \
-e SKILLSPECTOR_PROVIDER=openai \
-e OPENAI_API_KEY="${OPENAI_API_KEY}" \
skillspector scan /scan --format sarif --output /scan/report.sarif
After the container exits, report.sarif is available in the repository root for upload to your security dashboard.
Optimizing Scan Performance in CI Environments
For optimal CI/CD performance, adopt a tiered scanning strategy:
- Per-commit scans: Run static-only analysis (
--no-llm) for fast feedback on every pull request. This mode executes regex patterns, AST inspection, and OSV lookups without external LLM latency. - Scheduled deep scans: Configure nightly or weekly workflows that enable LLM semantic analysis (
--dynamicor omit--no-llm) for comprehensive false-positive reduction and complex vulnerability detection.
Static scans typically complete in seconds, while LLM-enhanced scans depend on API response times and token processing. The src/skillspector/graph.py implementation ensures that enabling the LLM stage only extends the workflow when explicitly configured, preserving CI speed for standard development cycles.
Summary
- SkillSpector integrates into CI/CD pipelines via SARIF output, consumed by GitHub Actions, GitLab CI, and Azure Pipelines.
- The static analysis stage (
--no-llm) provides fast, deterministic security checks suitable for per-commit validation. - SARIF reports are generated using
skillspector scan -f sarif -o report.sarifand uploaded via platform-specific actions or tasks. - Key source files include
src/skillspector/cli.py(CLI wrapper),src/skillspector/graph.py(workflow orchestration), andsrc/skillspector/sarif_models.py(format serialization). - For programmatic integration, use
graph.invoke()withuse_llm=Falseto generate SARIF payloads in Python scripts.
Frequently Asked Questions
What is the difference between static and LLM analysis in SkillSpector?
Static analysis uses regex patterns, AST inspection, and OSV database lookups to identify vulnerabilities rapidly without external dependencies. LLM analysis adds a semantic validation layer where language models evaluate static findings to reduce false positives and detect complex logic flaws. Static analysis runs by default; LLM analysis requires provider credentials and is enabled by omitting the --no-llm flag.
Why should I use SARIF format instead of JSON for CI integration?
SARIF is the industry-standard format for static analysis results, designed specifically for interoperability between security tools and CI platforms. While SkillSpector supports JSON output, SARIF files are natively consumed by GitHub Advanced Security, GitLab SAST dashboards, and Azure DevOps security reports, enabling automatic mapping of findings to specific code locations and severity levels without custom parsing.
How do I handle LLM provider credentials securely in CI pipelines?
Store API keys as encrypted CI/CD variables (GitHub Secrets, GitLab CI/CD Variables, or Azure Pipeline Secrets) and reference them via environment variables. SkillSpector reads credentials from standard environment variables like OPENAI_API_KEY, ANTHROPIC_API_KEY, or NVIDIA_API_KEY, and selects the provider via SKILLSPECTOR_PROVIDER. Never commit credentials to repository files.
Can I run SkillSpector without installing Python on my CI runners?
Yes. SkillSpector can run inside a Docker container. Build the image from the repository or use a pre-built version, mount your source code as a volume, and execute the scan command. The SARIF output is written to the mounted volume, making the report available to the CI runner for upload without requiring Python on the host system.
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 →