Trivy can actually prevent your builds from completing if they include forbidden open-source licenses, not just report them.

Here’s what a build looks like when Trivy blocks it due to a forbidden license:

$ trivy fs --exit-code 1 --severity HIGH --license-group "forbidden" .
2023-10-27T10:30:00.123Z INFO    Detected OS (debian 11)
2023-10-27T10:30:00.123Z INFO    Detecting vulnerabilities...
...
2023-10-27T10:30:05.456Z ERROR   License "GPL-2.0-only" is found in "github.com/gin-gonic/gin@v1.7.7" which is classified as forbidden.
2023-10-27T10:30:05.456Z INFO    Exit Code: 1

The key here is the --exit-code 1 flag. When Trivy encounters a license it deems problematic (based on your configuration), it will exit with a non-zero status code, which most build systems interpret as a failure. The --severity HIGH flag is used in conjunction with license groups to filter which license findings trigger the exit code.

To make this work, you need to define what constitutes a "forbidden" license. Trivy uses license groups for this. You can create a custom configuration file (e.g., trivy-config.yaml) to define these groups.

Here’s an example trivy-config.yaml that defines a "forbidden" group including the GPL-2.0 license:

license:
  # Override default license classifiers
  # classifiers:
  #   - name: permissive
  #     keywords:
  #       - MIT
  #       - Apache-2.0
  #   - name: restrictive
  #     keywords:
  #       - GPL-2.0-only
  #       - GPL-3.0-only
  #       - AGPL-1.0-only
  #       - AGPL-3.0-only

  # Define license groups
  license-groups:
    - name: forbidden
      licenses:
        - GPL-2.0-only
        - GPL-3.0-only
    - name: copyleft
      licenses:
        - LGPL-2.1-only
        - AGPL-1.0-only

You then tell Trivy to use this configuration file with the --config flag:

trivy fs --config trivy-config.yaml --exit-code 1 --severity HIGH --license-group "forbidden" .

In this command:

  • --config trivy-config.yaml: Points Trivy to your custom configuration.
  • --exit-code 1: Ensures Trivy exits with a non-zero status on a violation.
  • --severity HIGH: This is crucial. Trivy assigns severities to license findings. By default, licenses in your forbidden group are often classified as HIGH. This flag ensures that only HIGH severity findings (which will include your forbidden licenses) trigger the exit code. You can inspect the severity of a specific license by running Trivy without --exit-code 1 and looking at the output.
  • --license-group "forbidden": This tells Trivy to only consider licenses that are part of the "forbidden" group for this specific check.

The "why it works" is simple: build systems (like Jenkins, GitLab CI, GitHub Actions, etc.) monitor the exit code of commands they execute. A non-zero exit code signals an error, and the build pipeline is halted. Trivy leverages this standard behavior to enforce your licensing policies.

What if you want to block licenses that are not explicitly listed as forbidden but are generally considered restrictive? Trivy’s default classifiers already categorize licenses. You can modify or extend these classifiers in your trivy-config.yaml. For example, if you want to block all GPL variants, you could uncomment and adjust the classifiers section in the example config to put GPL-2.0-only, GPL-3.0-only, etc., into a restrictive category, and then use --license-group "restrictive" with --severity HIGH.

The most surprising thing about Trivy’s license blocking is how granular you can get with severity. While you might think a "forbidden" license is always a critical failure, Trivy allows you to assign severities like UNKNOWN, LOW, MEDIUM, and HIGH to license findings. This means you can configure your CI/CD pipeline to only fail the build for HIGH severity license violations, even if your forbidden group contains licenses that Trivy might otherwise classify as MEDIUM. You can inspect the assigned severity by running trivy fs --format json . and examining the Results[].Violations[].Severity field for license-related findings.

The next hurdle you’ll likely face is integrating this into your existing CI/CD workflows, ensuring the trivy-config.yaml is accessible and that the build steps are correctly ordered to catch violations early.

Want structured learning?

Take the full Trivy course →