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

> Learn to integrate SkillSpector into GitLab CI for automated AI agent security scanning. Generate SARIF reports and set risk score thresholds to ensure code quality.

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

---

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

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

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

```dockerfile
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`](https://github.com/NVIDIA/SkillSpector/blob/main/entrypoint.sh) script forwards arguments to the CLI:

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

```

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

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

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

```yaml
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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/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`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/sarif_models.py) and built by the `_build_sarif` method in [`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py) (lines 360-403). This version is fully compatible with GitLab's built-in code quality and security report parsers.