How to Integrate SkillSpector into CI/CD Pipelines: Automated Security Scanning Guide
To integrate SkillSpector into CI/CD pipelines, run the CLI with -f sarif -o report.sarif to generate a SARIF report and upload it to your platform’s security dashboard, using --no-llm for deterministic static-only scans on every commit.
NVIDIA/SkillSpector is a Python-based security scanner that analyzes AI-agent skill packages—including SKILL.md files, source code, and dependencies—through a two-stage LangGraph workflow. When you integrate SkillSpector into CI/CD pipelines, you automate risk scoring and vulnerability detection with native SARIF output that feeds directly into GitHub Advanced Security, GitLab Secure, and Azure DevOps dashboards.
Understanding the SkillSpector Architecture
SkillSpector implements a two-stage analysis pipeline in src/skillspector/graph.py that produces CI-friendly output:
- Static analysis – Fast regex-driven pattern matching, AST inspection, and live OSV vulnerability lookups that execute deterministically without external API calls.
- Optional LLM semantic analysis – A language-model validation step that reduces false positives by semantically analyzing static findings.
The graph.invoke() method returns a dictionary containing report_body and sarif_report keys. According to the source code in src/skillspector/sarif_models.py, the SARIF 2.1 schema serialization supports multi-run reports where the first run contains static findings and a second run (only when LLM analysis is enabled) contains dynamic validation results.
Key Integration Points in the Source Code
Understanding these specific files helps customize your pipeline integration:
src/skillspector/cli.py– Parses arguments, builds the initial graph state, and handles file I/O for SARIF generation via the-f sarifflag.src/skillspector/graph.py– Instantiates the LangGraph workflow, orchestrates static and LLM nodes, and returns the unified result object.src/skillspector/sarif_models.py– Serializes internal findings into the SARIF 2.1 schema attached toresult["sarif_report"].src/skillspector/providers/– Contains adapters for OpenAI, Anthropic, and NVIDIA LLM providers that read credentials from environment variables.src/skillspector/constants.py– Defines default risk-scoring values, pattern IDs, and severity thresholds used in CI gate decisions.
GitHub Actions Integration
For GitHub repositories, generate a SARIF file on every push and upload it to Code Scanning alerts.
name: SkillSpector 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
The --no-llm flag ensures deterministic, fast execution suitable for PR checks. The upload-sarif action ingests the report into the Security tab.
GitLab CI Configuration
GitLab’s built-in SAST report format accepts SARIF files directly through the artifacts:reports:sast keyword.
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
This conditional logic enables LLM analysis only when the ANTHROPIC_API_KEY variable is present in protected CI variables, falling back to static-only scans for public runners.
Programmatic Integration via Python API
For custom pipeline logic or pre-upload processing, invoke the LangGraph workflow directly:
from skillspector.graph import graph
import json
result = graph.invoke({
"input_path": "./my-skill",
"output_format": "sarif",
"use_llm": False,
})
# Access the SARIF payload from the result dictionary
with open("report.sarif", "w", encoding="utf-8") as f:
json.dump(result["sarif_report"], f, indent=2)
This approach bypasses the CLI file handling in src/skillspector/cli.py and allows you to manipulate the sarif_report object before writing it to disk.
Docker-Based CI Execution
For environments without Python installed, use a containerized approach:
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 Azure Pipelines using PublishSecurityAnalysisLogs@3 or similar platform-specific tasks.
Optimizing Scan Performance in CI/CD
Static-only scans (--no-llm) provide repeatable, fast feedback suitable for every commit and pull request. These scans execute entirely within the CI runner without external LLM API calls.
LLM-enhanced scans require setting provider credentials (OPENAI_API_KEY, ANTHROPIC_API_KEY, or NVIDIA_API_KEY) and the SKILLSPECTOR_PROVIDER environment variable. According to the implementation in src/skillspector/providers/, these scans add network latency and token costs. Best practice is to run static scans on every commit and schedule LLM validation as a nightly workflow on the main branch.
Summary
- Install SkillSpector via pip or Docker in your CI job.
- Generate SARIF output using
-f sarif -o report.sarifto ensure compatibility with security dashboards. - Use
--no-llmfor deterministic, fast static analysis on every commit. - Upload the SARIF file using platform-native actions:
github/codeql-action/upload-sariffor GitHub Actions,artifacts:reports:sastfor GitLab CI, orPublishSecurityAnalysisLogs@3for Azure Pipelines. - Reference key files like
src/skillspector/graph.pyandsrc/skillspector/sarif_models.pywhen customizing the scan workflow or parsing results programmatically.
Frequently Asked Questions
How do I enable LLM analysis in SkillSpector pipelines?
Set the SKILLSPECTOR_PROVIDER environment variable to openai, anthropic, or nvidia, and provide the corresponding API key (e.g., OPENAI_API_KEY). Omit the --no-llm flag when calling skillspector scan. The LLM step validates static findings to reduce false positives, but adds API latency and cost.
What is the difference between static and LLM analysis in CI/CD?
Static analysis runs regex patterns, AST inspection, and OSV vulnerability lookups locally without external dependencies, producing deterministic results ideal for gating pull requests. LLM analysis adds a semantic validation layer that interprets findings contextually, suitable for deep security reviews rather than per-commit checks.
Which CI platforms support SkillSpector SARIF output?
All major platforms support SARIF 2.1 ingestion: GitHub Actions via upload-sarif, GitLab CI via artifacts:reports:sast, Azure Pipelines via PublishSecurityAnalysisLogs@3, and Bitbucket Pipelines via third-party SARIF viewers. The multi-run SARIF structure in src/skillspector/sarif_models.py preserves provenance between static and dynamic findings.
Can I run SkillSpector without installing Python on the CI runner?
Yes. Build a Docker image containing SkillSpector and mount your repository as a volume. The container executes the scan and writes the SARIF file back to the host filesystem. This approach isolates dependencies and ensures consistent environments across GitHub Actions, GitLab CI, and Azure Pipelines.
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 →