How to Integrate SkillSpector into Your CI/CD Pipeline for Automated AI Security Scanning

Integrate SkillSpector into your CI/CD pipeline by running skillspector scan --format sarif --output report.sarif --no-llm and uploading the resulting SARIF file to your platform's security dashboard, enabling automated vulnerability detection for every code change.

NVIDIA/SkillSpector is a Python-based security scanner that analyzes AI-agent skill packages—including SKILL.md files, source code, and dependencies—to produce risk scores and remediation guidance. By adding it to your continuous integration workflow, you can enforce security gates that block risky deployments while leveraging the SARIF 2.1 standard for native integration with GitHub Actions, GitLab CI, and Azure Pipelines.

Understanding SkillSpector's CI/CD Architecture

SkillSpector is built around a two-stage LangGraph workflow defined in src/skillspector/graph.py. This architecture separates fast deterministic checks from computationally intensive analysis, making it ideal for CI environments where speed matters.

The Two-Stage Analysis Workflow

The workflow orchestrates two distinct nodes:

  1. Static Analysis – Performs regex-driven pattern matching, AST inspection, and live OSV vulnerability lookups using rules defined in src/skillspector/constants.py. This stage is deterministic and requires no external API calls beyond OSV database queries.
  2. Optional LLM Semantic Analysis – Validates static findings using language models (OpenAI, Anthropic, or NVIDIA) via adapters in src/skillspector/providers/. This reduces false positives but adds latency and non-determinism.

When you invoke the CLI from src/skillspector/cli.py, the tool builds the initial graph state, executes the workflow, and serializes results through src/skillspector/sarif_models.py, which implements the SARIF 2.1 schema.

SARIF as the Integration Bridge

The SARIF (Static Analysis Results Interchange Format) output is the key to CI/CD integration. SkillSpector emits a multi-run SARIF object where the first run contains static findings and a second run (only when LLM analysis is enabled) contains semantic validation results. This structure allows security dashboards to display provenance information for each vulnerability, showing whether it originated from static pattern matching or LLM verification.

Configuring SkillSpector for CI/CD Environments

Static-Only vs. LLM-Enhanced Scans

For CI pipelines, run static-only scans using the --no-llm flag to ensure fast, reproducible results on every commit. Static analysis completes in seconds and requires no API keys, making it suitable for pull request gates.

Reserve LLM-enhanced scans (omit --no-llm) for nightly workflows or scheduled security reviews where you can tolerate variable latency and have configured the appropriate provider credentials.

Required Environment Variables

When enabling LLM analysis, set these environment variables in your CI secrets:

  • SKILLSPECTOR_PROVIDER – Specifies the backend (openai, anthropic, or nvidia).
  • OPENAI_API_KEY, ANTHROPIC_API_KEY, or NVIDIA_API_KEY – Authentication tokens for the respective provider.

The provider modules in src/skillspector/providers/ handle credential lookup automatically, falling back to standard environment variable names.

CI/CD Integration Examples

GitHub Actions Workflow

Use the official github/codeql-action/upload-sarif action to ingest SkillSpector reports into GitHub's security dashboard.

name: SkillSpector Security Scan
on:
  push:
    branches: [main]
  pull_request:
    paths:
      - '**.md'
      - '**.py'
      - '**/requirements.txt'

jobs:
  security-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 . --format sarif --output report.sarif --no-llm

      - name: Upload SARIF to GitHub Code Scanning
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: report.sarif

GitLab CI Configuration

GitLab's built-in SAST integration consumes SARIF files directly through the artifacts:reports:sast keyword.

skillspector_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 . --format sarif --output report.sarif
      else
        skillspector scan . --format sarif --output report.sarif --no-llm
      fi
  artifacts:
    reports:
      sast: report.sarif
    expire_in: 1 week

Python API for Custom Pipelines

For complex workflows requiring custom logic, invoke SkillSpector programmatically using the LangGraph instance from src/skillspector/graph.py:

from skillspector.graph import graph
import json

def run_security_scan(skill_path: str, output_path: str):
    """Execute static scan and write SARIF output."""
    result = graph.invoke({
        "input_path": skill_path,
        "output_format": "sarif",
        "use_llm": False,  # Static-only for CI speed

    })
    
    with open(output_path, "w", encoding="utf-8") as f:
        json.dump(result["sarif_report"], f, indent=2)
    
    # Exit with error if high-risk findings detected

    if result.get("risk_score", 0) > 7:
        raise SystemExit("High-risk security findings detected")

if __name__ == "__main__":
    run_security_scan("./my-skill-package", "report.sarif")

Docker-Based Execution

If you prefer not to install Python dependencies on your runners, use a containerized approach:


# Build once, use in pipeline

docker build -t skillspector:latest .

# Run scan in CI

docker run --rm \
  -v "$(pwd)":/workspace \
  -w /workspace \
  skillspector:latest \
  scan /workspace --format sarif --output /workspace/report.sarif --no-llm

# For LLM-enabled scans, inject credentials

docker run --rm \
  -v "$(pwd)":/workspace \
  -e SKILLSPECTOR_PROVIDER=openai \
  -e OPENAI_API_KEY="${OPENAI_API_KEY}" \
  skillspector:latest \
  scan /workspace --format sarif --output /workspace/report.sarif

Understanding the SARIF Output Structure

The sarif_report object generated by src/skillspector/sarif_models.py contains two runs when full analysis is enabled:

  1. Static Analysis Run – Contains findings from regex patterns and AST analysis, with rule IDs defined in src/skillspector/constants.py.
  2. LLM Validation Run – Contains semantic analysis results that confirm or dismiss static findings, reducing false positives.

Each run includes severity labels (critical, high, medium, low) and remediation suggestions that map directly to your CI platform's security alert fields. For detailed schema documentation, refer to the design specification in docs/plans/2026-04-03-skilltrap-integration.md.

Summary

  • Install SkillSpector via pip or Docker, then invoke skillspector scan --format sarif to generate standardized security reports.
  • Use --no-llm in pull request workflows for deterministic, fast static analysis; reserve LLM scans for scheduled nightly jobs.
  • Upload SARIF files to GitHub Code Scanning, GitLab SAST, or Azure DevOps using native platform actions that consume the SARIF 2.1 format.
  • Configure credentials via environment variables (SKILLSPECTOR_PROVIDER, OPENAI_API_KEY, etc.) when enabling semantic analysis through the provider modules in src/skillspector/providers/.
  • Reference source files (cli.py, graph.py, sarif_models.py) to understand how the LangGraph workflow orchestrates analysis and generates CI-compatible output.

Frequently Asked Questions

What output format should I use for CI/CD integration?

Use SARIF (--format sarif) because it is the industry standard for static analysis result interchange. The src/skillspector/sarif_models.py file implements the SARIF 2.1 schema, producing output that GitHub Actions, GitLab CI, and Azure Pipelines can ingest natively for security dashboard visualization.

How do I handle LLM provider credentials in CI environments?

Set the SKILLSPECTOR_PROVIDER environment variable to specify your backend (openai, anthropic, or nvidia), and provide the corresponding API key (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.) as a masked CI variable. The provider adapters in src/skillspector/providers/ automatically detect these variables. For pull request scans, use --no-llm to avoid exposing credentials and reduce costs.

Can I run SkillSpector without installing Python on my CI runners?

Yes. Build a Docker image containing SkillSpector and mount your repository as a volume. Execute docker run with the scan command and output the SARIF file to the mounted volume. This approach isolates dependencies and ensures consistent execution across different CI platforms.

How do I interpret the risk scores in the SARIF output?

Risk scores are calculated based on rules defined in src/skillspector/constants.py, combining vulnerability severity from OSV databases with pattern match confidence. Scores range from 0 (low risk) to 10 (critical). In the SARIF output, these map to the properties field of each result, allowing you to configure CI gates that fail builds when scores exceed thresholds (e.g., blocking merges on scores > 7).

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 →