How to Use SkillSpector in GitLab CI: Automated Security Scanning for AI Agents

TLDR: SkillSpector integrates with GitLab CI by executing the skillspector scan command in your pipeline, generating SARIF 2.1.0 reports that GitLab parses as code quality artifacts, and optionally failing jobs when the computed risk score exceeds configurable thresholds.

SkillSpector is NVIDIA's open-source security scanner that combines static analysis with optional Large Language Model (LLM) evaluation to identify vulnerabilities in AI agent skills. When you configure SkillSpector in your GitLab CI/CD workflow, you enable continuous automated security vetting for every commit and merge request. This guide provides production-ready configuration examples and references specific source files from the NVIDIA/SkillSpector repository to ensure your implementation aligns with the tool's architecture.

How SkillSpector Integrates with GitLab CI

The SkillSpector CLI follows a predictable execution flow designed for CI environments. In src/skillspector/cli.py, the scan command (lines 35-55) parses arguments, builds the initial graph state, and invokes the LangGraph workflow that orchestrates the security analysis.

The InputHandler class in src/skillspector/input_handler.py automatically detects GitLab URLs through the _is_git_url method (lines 105-117), which recognizes gitlab.com and other Git hosts. When a Git URL is detected, the _clone_git method (lines 125-139) performs a shallow clone into a temporary directory that the analysis graph consumes. This eliminates the need for manual checkout steps in your CI configuration.

After analysis completes, the report node in src/skillspector/nodes/report.py builds a SARIF 2.1.0 log via the _build_sarif method (lines 360-403). The CLI writes this output to disk through the _write_result function (lines 111-121) in cli.py, producing a file that GitLab's built-in security and code quality parsers can consume directly.

Configuring Your GitLab CI Pipeline

Basic CI/CD Configuration

Create a .gitlab-ci.yml file that installs SkillSpector and executes the scan against your repository. The configuration below uses the $CI_PROJECT_URL variable to automatically target the current project:

stages:
  - test

skill_spector_scan:
  stage: test
  image: python:3.12-slim
  variables:
    SKILLSPECTOR_PROVIDER: openai
    OPENAI_API_KEY: $OPENAI_API_KEY
  script:
    - pip install --no-cache-dir skillspector
    - |
      skillspector scan \
        "$CI_PROJECT_URL" \
        --format sarif \
        --output report.sarif \
        --no-llm
  artifacts:
    reports:
      codequality: report.sarif
    paths:
      - report.sarif
    expire_in: 1 week

According to the NVIDIA/SkillSpector source code, the --format sarif flag triggers SARIF 2.1.0 generation via the Pydantic models defined in src/skillspector/sarif_models.py. GitLab automatically parses this artifact and surfaces findings in the merge request UI under the Code Quality tab.

Enforcing Security Policies with Risk Scores

To fail the pipeline when vulnerabilities exceed your risk tolerance, extract the risk_score field from the SARIF output. The report.py file (line 412) includes this value in the root dictionary of the SARIF payload. Use jq to parse the JSON and exit with an error code:

script:
  - pip install --no-cache-dir skillspector
  - skillspector scan "$CI_PROJECT_URL" --format sarif --output report.sarif --no-llm
  - |
    jq '.risk_score' < report.sarif | grep -q -v '^([0-4][0-9]|[0-9])$' && exit 1 || true

This configuration fails the job if the risk score exceeds 50, blocking merges that introduce high-severity vulnerabilities.

Advanced Configuration Options

Using Custom Docker Images

Avoid runtime dependency installation by building a custom image containing SkillSpector and your preferred LLM provider. Create a Dockerfile in your repository:

FROM python:3.12-slim
RUN pip install --no-cache-dir skillspector[anthropic]
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

The entrypoint.sh script forwards arguments to the CLI:

#!/bin/bash
exec skillspector "$@"

Push this image to your GitLab registry and reference it in your pipeline:

skill_spector_scan:
  image: registry.example.com/skillspector:latest
  script:
    - skillspector scan "$CI_PROJECT_URL" --format sarif --output report.sarif

Accessing Private GitLab Repositories

When scanning private repositories, inject a personal access token into the URL. Store GITLAB_TOKEN as a protected CI/CD variable with read_repository scope:

script:
  - |
    GIT_URL="https://oauth2:${GITLAB_TOKEN}@gitlab.com/${CI_PROJECT_PATH}.git"
    skillspector scan "$GIT_URL" --format sarif --output report.sarif

The InputHandler._is_git_url method in src/skillspector/input_handler.py correctly parses these authenticated URLs to trigger the cloning workflow.

Configuring LLM Providers

For reproducible LLM-assisted analysis, pin specific models using environment variables. The provider implementations in src/skillspector/providers/ read these values during initialization:

variables:
  SKILLSPECTOR_PROVIDER: anthropic
  SKILLSPECTOR_MODEL: claude-3-opus-20240229
  ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY

Remove the --no-llm flag from your scan command to enable LLM analysis. Note that static-only analysis (--no-llm) executes faster and consumes no API tokens, making it ideal for standard CI checks.

Summary

  • SkillSpector automatically detects GitLab URLs via InputHandler._is_git_url and clones repositories without manual configuration.
  • SARIF 2.1.0 output integrates natively with GitLab's code quality reports, surfacing findings directly in merge requests.
  • Risk score thresholds can gate your pipeline by parsing the SARIF JSON with standard tools like jq.
  • Private repositories require token-based authentication passed through the URL scheme.
  • Static-only mode (--no-llm) provides deterministic, fast security scanning suitable for CI environments.

Frequently Asked Questions

How does SkillSpector recognize GitLab repositories in CI?

SkillSpector detects GitLab URLs through the _is_git_url method in src/skillspector/input_handler.py (lines 105-117), which identifies gitlab.com domains and other Git hosts. When a GitLab URL is supplied to the scan command, the _clone_git method (lines 125-139) automatically performs a shallow clone into a temporary directory for analysis.

Can I use SkillSpector in GitLab CI without LLM dependencies?

Yes. Append the --no-llm flag to your scan command to run static analysis only. This mode is deterministic, requires no API keys, and executes significantly faster than LLM-assisted scanning, making it ideal for standard CI pipelines where speed and cost are priorities.

How do I fail a GitLab CI job based on SkillSpector's risk score?

The SARIF output includes a risk_score field at the root level (as implemented in src/skillspector/nodes/report.py). Parse this value using jq and exit with a non-zero status code if the score exceeds your threshold. For example: jq '.risk_score' < report.sarif | grep -q -v '^([0-4][0-9]|[0-9])$' && exit 1.

What SARIF version does SkillSpector output for GitLab compatibility?

SkillSpector generates SARIF 2.1.0 logs, as defined by the Pydantic models in src/skillspector/sarif_models.py and built by the _build_sarif method in src/skillspector/nodes/report.py (lines 360-403). This version is fully compatible with GitLab's built-in code quality and security report parsers.

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 →