Skip to content
CloudOps
All prompts
AI for GitLab CI/CD Difficulty: Intermediate ClaudeChatGPT

GitLab Dependency Scanning & SBOM Generation Prompt

Configure GitLab dependency scanning, generate SBOMs (CycloneDX, SPDX), license compliance checks, and supply-chain visibility.

Target user
DevOps and security engineers managing supply-chain risk
Difficulty
Intermediate
Tools
Claude, ChatGPT

The prompt

You are a senior DevOps / AppSec engineer who has built supply-chain visibility — dependency scanning, SBOM generation, license compliance — across many GitLab projects.

I will provide:
- The languages / package managers in use (npm, pip, Go modules, Maven, Cargo, Bundler, etc.)
- GitLab tier (some features Ultimate)
- SBOM format requirements (CycloneDX, SPDX) and where SBOMs go (artifact, registry, internal portal)
- License policy (allowed/disallowed)

Your job:

1. **GitLab Dependency Scanning**:
   - Template: `Security/Dependency-Scanning.gitlab-ci.yml`
   - Scans `package-lock.json`, `Gemfile.lock`, `requirements.txt`, `go.sum`, `pom.xml`, etc.
   - Findings reported in MR widget + Security Dashboard
   - Supports many ecosystems; auto-detects lock files
2. **SBOM generation**:
   - GitLab's `Dependency-Scanning` produces a "dependency list" + CycloneDX SBOM (`gl-sbom-*.cdx.json`)
   - Artifact format: `artifacts:reports:cyclonedx`
   - Distributed by: include in release artifacts, push to artifact registry, expose via GitLab's dependency list UI
3. **For language-specific tooling** (if not using GitLab default):
   - Node: `npm sbom` (npm 10+) or `cyclonedx-npm`
   - Python: `cyclonedx-py`
   - Go: `cyclonedx-gomod`
   - Java: `cyclonedx-maven-plugin`, `cyclonedx-gradle-plugin`
   - Rust: `cargo-cyclonedx`
   - Container image: `syft` from Anchore (gives SBOM for OS+app layers)
4. **For license compliance**:
   - GitLab License Compliance: `Security/License-Scanning.gitlab-ci.yml` (older) or built into Dependency-Scanning
   - Configure approved / denied license list
   - Block merges that introduce disallowed licenses
5. **For container SBOM**:
   - Use `syft <image> -o cyclonedx-json > image-sbom.json`
   - Or container scanning template generates one
   - Push SBOM to artifact registry alongside image (OCI artifacts)
6. **For continuous tracking**:
   - GitLab's dependency list (Ultimate): per-project view of all deps with vuln status
   - For org-wide: aggregate via API
7. **For supply-chain attestations** (advanced):
   - SLSA provenance generation
   - Sigstore / cosign signing of artifacts AND SBOMs
   - In-toto attestations
8. **For new CVE response** (e.g., when a Log4Shell-class event happens):
   - Search dependency list / SBOMs for the affected package + version
   - Triage projects; create issues; track patching

Mark DESTRUCTIVE: ignoring license violations to "fix later" (legal exposure), publishing artifacts without SBOM (no supply-chain visibility downstream), trusting SBOMs from untrusted sources without verification.

---

Languages / package managers: [DESCRIBE]
GitLab tier: [Free / Premium / Ultimate]
SBOM format target: [CycloneDX / SPDX / both]
License policy: [DESCRIBE — allowed/disallowed list]
Goal: [enable / tune / SBOM-as-output / CVE-search]

Why this prompt works

SBOM and dependency scanning are foundational for supply-chain security but often partially implemented. This prompt walks the GitLab built-in path AND complementary tooling.

How to use it

  1. Enable Dependency Scanning — it’s free and broad.
  2. Add CycloneDX SBOM — output as artifact for downstream.
  3. For containers, add syft separately.
  4. Build a CVE-search habit — when a new high-impact CVE drops, search SBOMs.

Useful commands

# Dependency list via API (Ultimate)
curl --header "PRIVATE-TOKEN: <t>" \
    "https://gitlab.example.com/api/v4/projects/<id>/dependencies?package_manager=npm" | jq

# Search for a specific package
curl --header "PRIVATE-TOKEN: <t>" \
    "https://gitlab.example.com/api/v4/projects/<id>/dependencies?package_manager=npm" | \
    jq '.[] | select(.name=="lodash")'

# Generate SBOM with syft (container image)
syft alpine:3.20 -o cyclonedx-json > sbom.json
syft <my-image> -o spdx-json > sbom.spdx.json

# Generate SBOM for source tree
syft . -o cyclonedx-json > source-sbom.json

# Scan an SBOM for vulnerabilities (with Grype)
grype sbom:sbom.json

Patterns

GitLab Dependency Scanning + SBOM

include:
- template: Security/Dependency-Scanning.gitlab-ci.yml

gemnasium-dependency_scanning:
  artifacts:
    reports:
      dependency_scanning: gl-dependency-scanning-report.json
      cyclonedx: "**/gl-sbom-*.cdx.json"
    paths:
      - "**/gl-sbom-*.cdx.json"
    expire_in: 1 week

Add syft for container SBOM

container-sbom:
  stage: scan
  image:
    name: anchore/syft:latest
    entrypoint: [""]
  script:
    - syft "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" -o cyclonedx-json > container-sbom.json
    - syft "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" -o spdx-json > container-sbom.spdx.json
  artifacts:
    paths:
      - container-sbom.json
      - container-sbom.spdx.json
    expire_in: 30 days
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

License compliance configuration

# Already part of Dependency-Scanning template in newer GitLab
variables:
  DS_INCLUDE_DEV_DEPENDENCIES: "false"        # exclude devDeps

In Project → Security → Policies, configure allowed/denied licenses.

Container SBOM-as-OCI-artifact (advanced)

push-sbom:
  needs: [container-sbom]
  script:
    - oras push "$CI_REGISTRY_IMAGE/sbom:$CI_COMMIT_SHORT_SHA" \
        container-sbom.json:application/vnd.cyclonedx+json

CVE search across projects (when a new CVE hits)

#!/bin/bash
# Search all projects in a group for a vulnerable package
GROUP_ID=42
PACKAGE="log4j-core"
VERSION_LT="2.17.0"

curl --header "PRIVATE-TOKEN: $TOKEN" \
    "https://gitlab.example.com/api/v4/groups/$GROUP_ID/projects?include_subgroups=true" | \
    jq -r '.[].id' | \
    while read PROJ_ID; do
        AFFECTED=$(curl -s --header "PRIVATE-TOKEN: $TOKEN" \
            "https://gitlab.example.com/api/v4/projects/$PROJ_ID/dependencies" | \
            jq -r --arg pkg "$PACKAGE" '.[] | select(.name==$pkg) | .version')
        if [ -n "$AFFECTED" ]; then
            echo "Project $PROJ_ID: $PACKAGE versions: $AFFECTED"
        fi
    done

Common findings this catches

  • Transitive deps not scanned — lockfile missing; scanner only sees top-level.
  • CycloneDX format vs SPDX — pick one for downstream consumers; both isn’t wrong but maintenance overhead.
  • License findings on a multi-license package — verify actual LICENSE; may be misclassified.
  • Container SBOM missing app deps — syft scans only manifest files in image; if app uses runtime-loaded plugins, need additional scanning.
  • Dependency list shows packages no longer in code — old lockfile not regenerated; refresh.
  • SBOMs not retained long enough for incident response — set expire_in: 90 days or longer.

When to escalate

  • Legal / license violation requires fix — engage legal; replace dep or change licensing.
  • Critical CVE in widely-used dependency — incident response; track patches across portfolio.
  • Supply-chain attack suspected — coordinate with security; verify build provenance.

Related prompts

Newsletter

Get weekly AI workflows for DevOps engineers

Practical prompts, automation ideas, and tool reviews for infrastructure engineers. One email per week. No spam.