In Trivy 0.74, how does `--scanners license` decide whether a detected license is CRITICAL, HIGH or UNKNOWN, and how do you change that?
answer
- a borrowed classification, mapped to severity
- seven categories, forbidden to unknown
- lists that live only in the config file
- AND takes the worst, OR the best
basics
~20 sTrivy sorts each license into Google's license categories and maps them to severity: forbidden CRITICAL, restricted HIGH, reciprocal MEDIUM, notice, permissive and unencumbered LOW, unrecognised UNKNOWN. The lists live under license in trivy.yaml; --ignored-licenses drops named licenses.
solid answer
~40 sLicense scanning is off by default, since `trivy image` runs `vuln,secret`, so you add `--scanners license`. Trivy reads license metadata from installed OS and language packages and classifies each license with the Google License Classification: `forbidden` is CRITICAL, `restricted` HIGH, `reciprocal` MEDIUM, `notice`, `permissive` and `unencumbered` LOW, and anything it cannot place is UNKNOWN, shown as "Non Standard" in the table. For an SPDX expression, `AND` takes the most severe part, `OR` the least severe, and one unknown part makes the whole expression UNKNOWN. To change the verdicts you edit the category lists under `license:` in `trivy.yaml`, which have no CLI flags. `--ignored-licenses MIT,Apache-2.0` removes named licenses from the results, and `--license-full` also reads license files and source headers.
code
bash · 2 linestrivy image --scanners license --severity HIGH,CRITICAL --ignored-licenses MPL-2.0 registry.example.internal/shop/app:1.4
trivy fs --scanners license --license-full --severity UNKNOWN,HIGH,CRITICAL ./vendorgo deeper
Recall that license scanning needs --scanners license and that Trivy maps license categories to severities, forbidden being the highest.
Explain the category-to-severity table, how AND and OR expressions combine, and where the lists are changed: trivy.yaml, not flags.
Show judgement about noise and blind spots: --ignored-licenses for accepted licenses, --license-full for vendored code, and UNKNOWN findings that still need a human look.
Separate the scanner's classification from the organisation's license policy, and decide who owns the category lists so that changes are reviewed rather than edited ad hoc.
## Turning license scanning on Trivy's scanners are chosen with `--scanners`. For `trivy image` and `trivy fs` the default is `vuln,secret`, so license findings appear only when you ask for them: `--scanners license` alone, or `--scanners vuln,license` alongside vulnerabilities. On `trivy sbom` the scanner reads the license fields recorded in the SBOM. There are two depths of scanning: - **Standard** reads the license that package metadata declares: packages installed by `apk`, `apt-get`, `dnf`, `npm`, `pip`, `gem` and the other supported package managers. Some lockfiles need extra files, such as a package cache, before a license can be found. - **Full**, with `--license-full`, also classifies source files, Markdown documents, text files and `LICENSE` documents, and reports them in a separate **loose-file licenses** section. It catches vendored code and bundled assets that have no package record. It is slow, and it keeps only matches at or above `--license-confidence-level`, which defaults to `0.9`. `--license-full` is not offered on `trivy sbom`, which has no files to read. ## Categories and severities Trivy uses the **Google License Classification** and maps each category to a severity so that license findings sort alongside other findings: | Category | Severity | Examples from Trivy's default lists | |---|---|---| | `forbidden` | CRITICAL | AGPL-3.0, CC-BY-NC-4.0, WTFPL | | `restricted` | HIGH | GPL-2.0, LGPL-2.1 | | `reciprocal` | MEDIUM | MPL-2.0, EPL-2.0 | | `notice` | LOW | Apache-2.0, MIT, BSD-3-Clause | | `permissive` | LOW | empty by default | | `unencumbered` | LOW | CC0-1.0, Unlicense, 0BSD | | `unknown` | UNKNOWN | anything in no list; the table prints "Non Standard" | The severity says how restrictive the license category is. It says nothing about exploitability, and a CRITICAL license finding is not a vulnerability. ## Reading the output In table format, a license scan prints one section per kind of source: - **OS Packages (license)** lists each OS package with its license, classification and severity. - A section per language application, named after its lockfile or language, lists the libraries the same way. - **Loose File License(s)**, present only with `--license-full`, lists licenses found in files, with the file location instead of a package name. Each section starts with a total broken down by severity, so a reader can see at a glance how many restricted or forbidden licenses the image carries. In JSON output the same findings sit in each result's `Licenses` array, with the category and severity as fields. ## Compound expressions Packages often declare an **SPDX expression** rather than one license. Trivy classifies each part and combines them: - `AND`: the **most** severe part wins, because you must comply with both. `GPL-2.0-only AND MIT` is HIGH. - `OR`: the **least** severe part wins, because you may choose. `GPL-2.0-only OR MIT` is LOW. - If **any** part is unknown, the whole expression is UNKNOWN. A worked case: an image contains a library declared `LGPL-2.1-only OR MIT` and another declared `MPL-2.0 AND Apache-2.0`. The first is reported LOW, because MIT, a notice license, is the least severe choice. The second is reported MEDIUM, because MPL-2.0 is reciprocal and both parts apply. ## Changing the verdict 1. Write the defaults out with `trivy image --generate-default-config`, which creates `trivy-default.yaml`, and copy its `license:` section into your `trivy.yaml`. 2. Move license IDs between the lists `license.forbidden`, `license.restricted`, `license.reciprocal`, `license.notice`, `license.permissive` and `license.unencumbered`. These lists are configuration-file settings only. 3. For licenses Trivy sees only as text, add an entry with the `text://` prefix. The rest of the entry is a regular expression matched against the license text, for example `text://.* Apache Software .*`. Regex works only for text licenses, not for license IDs. 4. For licenses your organisation has accepted outright, `--ignored-licenses` removes their findings from the results. They are recorded as ignored and come back with `--show-suppressed`. 5. Use `--severity` to focus a report. The default shows all five severities, so a large image lists every LOW notice license. ## What the scan does not decide - **Legal obligations.** The categories are an engineering triage aid, not legal advice. - **Context.** A restricted license may matter in a shipped binary and not in an internal tool. Encoding that difference is a job for a policy rule over the findings, not for the scanner. - **The gate.** License findings that survive the filters count toward `--exit-code` like any other finding; how that is wired into CI is Trivy's CI integration.
- Why does `--license-full` find licenses the standard scan misses, and what does it cost?The standard scan trusts package-manager metadata. `--license-full` also classifies source files, Markdown, text files and LICENSE documents, so vendored code and bundled assets with no package record are found. It is slow, and it keeps only matches at or above `--license-confidence-level`, 0.9 by default.
- How do you classify a license that Trivy only sees as raw text?Add an entry with the `text://` prefix to a category list in `trivy.yaml`. The part after the prefix is a regular expression matched against the license text, for example `text://.* Apache Software .*` under `forbidden`. Regular expressions work only for text licenses, not for license IDs.
saying these in an interview costs you the question
- Trivy scans licenses on every image scan by default.
- A CRITICAL license finding means the package is exploitable.
- An OR expression is rated by its most restrictive license.
- Each license category can be overridden with its own command-line flag.
- Trivy's license categories are a legal opinion you can rely on.