# How to Integrate SkillSpector into CI/CD Pipelines: Automated Security Scanning Guide

> Integrate SkillSpector into CI/CD pipelines for automated security scanning. Generate SARIF reports and upload to your dashboard for continuous security monitoring. Optimize with --no-llm for static scans.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-06-25

---

**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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) that produces CI-friendly output:

1. **Static analysis** – Fast regex-driven pattern matching, AST inspection, and live OSV vulnerability lookups that execute deterministically without external API calls.
2. **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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py)** – Parses arguments, builds the initial graph state, and handles file I/O for SARIF generation via the `-f sarif` flag.
- **[`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py)** – Instantiates the LangGraph workflow, orchestrates static and LLM nodes, and returns the unified result object.
- **[`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py)** – Serializes internal findings into the SARIF 2.1 schema attached to `result["sarif_report"]`.
- **`src/skillspector/providers/`** – Contains adapters for OpenAI, Anthropic, and NVIDIA LLM providers that read credentials from environment variables.
- **[`src/skillspector/constants.py`](https://github.com/NVIDIA/SkillSpector/blob/main/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.

```yaml
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.

```yaml
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:

```python
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`](https://github.com/NVIDIA/SkillSpector/blob/main/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:

```bash
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.sarif` to ensure compatibility with security dashboards.
- **Use `--no-llm`** for deterministic, fast static analysis on every commit.
- **Upload the SARIF file** using platform-native actions: `github/codeql-action/upload-sarif` for GitHub Actions, `artifacts:reports:sast` for GitLab CI, or `PublishSecurityAnalysisLogs@3` for Azure Pipelines.
- **Reference key files** like [`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py) and [`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py) when 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`](https://github.com/NVIDIA/SkillSpector/blob/main/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.