# How to Integrate SkillSpector into a CI/CD Pipeline for Automated Security Scanning

> Automate security scanning with SkillSpector in your CI/CD pipeline. Learn how to integrate SkillSpector for powerful, automated code analysis and vulnerability detection.

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

---

**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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py)** – Parses command-line arguments, constructs the initial graph state, and handles report serialization including SARIF generation.
- **[`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py)** – Instantiates the LangGraph workflow, executes static and optional LLM analysis nodes, and returns a dictionary containing `report_body` and `sarif_report`.
- **[`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/constants.py)** (risk-scoring thresholds and pattern definitions).

### The Two-Stage Analysis Workflow

SkillSpector executes security checks through two sequential stages:

1. **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.
2. **Optional LLM Semantic Analysis** – A language-model validation step that reviews static findings to reduce false positives. Enabled when `--no-llm` is 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:

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

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

```bash
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-sarif` or the native `upload-sarif` action.
- **GitLab CI**: Configure `artifacts:reports:sast` in your job definition.
- **Azure Pipelines**: Use the `PublishSecurityAnalysisLogs@3` task.

## 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:

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

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

```

### Python API Integration

For custom CI scripts, invoke the LangGraph workflow directly via the Python API:

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

```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 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 (`--dynamic` or 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`](https://github.com/NVIDIA/SkillSpector/blob/main/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.sarif` and uploaded via platform-specific actions or tasks.
- Key source files include **[`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py)** (CLI wrapper), **[`src/skillspector/graph.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/graph.py)** (workflow orchestration), and **[`src/skillspector/sarif_models.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py)** (format serialization).
- For programmatic integration, use `graph.invoke()` with `use_llm=False` to 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.