I’ve been using Trivy in GitLab CI for a while now to scan container images for CVEs, as I covered in a previous post. But lately, I’ve needed more than just vulnerability data — I want to know what licenses my dependencies carry and whether any of them violate our internal policy. That’s where SBOM generation and license compliance checks come in, and Trivy handles both neatly within the same CI job.
Why SBOM and License Checks Belong in CI
Waiting until production to discover a GPL-licensed library in a proprietary product is too late. Legal teams get involved, remediation costs rise, and releases get delayed. By generating an SBOM (Software Bill of Materials) and checking license compliance during the build phase, you catch these issues early — when they’re cheap to fix.
Trivy can create SBOMs in SPDX or CycloneDX format and evaluate licenses against allow/deny lists. I run this as part of the test stage, right after unit tests but before building the final image. If a disallowed license is found, the pipeline fails and the merge request gets blocked.
Setting Up Trivy for SBOM and License Scanning
First, make sure Trivy is installed in your GitLab Runner. I use the official Aquasecurity image, which is lightweight and updated frequently.
Here’s a snippet from my .gitlab-ci.yml:
sbom_and_license_check:
stage: test
image: aquasec/trivy:latest
script:
- trivy fs --format spdx-json --output sbom.spdx.json .
- trivy fs --exit-code 1 --ignore-unfixed --severity HIGH,CRITICAL .
- trivy fs --format table --output license-report.txt --scanners license .
artifacts:
reports:
sbom: sbom.spdx.json
paths:
- license-report.txt
expire_in: 1 week
rules:
- if: $CI_MERGE_REQUEST_ID
The first command generates an SPDX-formatted SBOM of the entire filesystem (you can limit it to src/ or package.json if preferred). The second runs a standard vulnerability scan — I keep this to maintain parity with my earlier container scanning job. The third is the key: it scans for licenses and outputs a human-readable table.
Interpreting the License Report
The trivy fs --scanners license command checks each dependency’s declared license and compares it against Trivy’s built-in allowlist. By default, it flags licenses like GPL-3.0, AGPL-3.0, and SSLP as requiring review.
You can customize this behavior with a config file. I created .trivyignore to exempt certain fonts and documentation, and .trivy.yaml to set a strict deny list:
# .trivy.yaml
license:
denyList:
- GPL-3.0
- AGPL-3.0
- SSLP-1.0
ignoreFile: .trivyignore
If any denied license is found, Trivy returns a non-zero exit code and fails the job. The license-report.txt artifact shows exactly which package triggered the failure, making it easy for developers to fix.
Integrating SBOM into Your Supply Chain
Beyond compliance, the SBOM itself is valuable. I publish the SPDX JSON as a pipeline artifact and ingest it into our internal security portal, where it’s correlated with CVE feeds and license databases. This gives us a full picture of what’s in each build.
As I mentioned before in my post about container scanning, having an SBOM ready makes responding to vulnerabilities like Log4j much faster — you can instantly see if you’re affected and where.
Tips and Gotchas
- Scan the right scope: Scanning the entire repo can pick up licenses from CI scripts or Dockerfiles that don’t end up in the final artifact. Adjust paths as needed.
- Watch for transient dependencies: Build-time tools (like
devDependenciesin Node) may show up — decide whether they matter for your use case. - SBOM format matters: SPDX is widely accepted for compliance; CycloneDX is preferred in some toolchains. Trivy supports both via
--format.
Conclusion
Adding SBOM generation and license checking to GitLab CI with Trivy isn’t just about ticking a compliance box — it’s about shifting left on legal risk. With a few lines of YAML, you get visibility into what your software contains and whether it’s safe to ship. I’ve found it pairs well with vulnerability scanning, and now I consider both essential parts of my pipeline.
If you’re already using Trivy for CVE scans, extending it to SBOM and licenses is a low-effort, high-return step. Start with the default rules, tune them to your policy, and make the reports visible to both dev and legal teams.
Cover image: GNOME Project · PDM (Wikimedia Commons / kamu malı) · https://commons.wikimedia.org/wiki/File:GNOME_System_Monitor_Debian_Lenny.png
