Skip to main content

Goal

Keep a reviewed list of the open source components your project is allowed to contain, in a scanoss.json file in the repository. scanoss-cli marks the components on the list as approved in every scan, so your checks fail only on something new.

When to use it

  • Your pull request check fails on components you already know about and accept.
  • A scan reports a match you have reviewed and know to be wrong.
  • You want approvals to go through code review, with a history in Git.

Prerequisites

  • scanoss-cli and SCANOSS_API_KEY (see Recipes)
  • jq, to bootstrap the file from an existing scan

How scanoss-cli finds scanoss.json

scanoss-cli looks for scanoss.json (then settings.json) in the directory you scan. To use a file somewhere else, pass --settings <path>. scanoss-cli applies the rules after the results come back from the API, so they work the same for scan, scan wfp, and results.

Step 1: Bootstrap the approved list

Scan the project once, and turn every component it detected into an approval rule:
scanoss.bootstrap.json now contains one rule per component:
Review the list before you use it. Every component in it counts as approved from now on. Then save it as scanoss.json. If you already have a scanoss.json (for example, with skip settings), copy the bom section into it instead of overwriting the file. Commit scanoss.json to the repository. Require a review from your open source owner for changes to it, using your code hosting’s review rules. That review is your approval process.

Step 2: Approve new components as they appear

When a check reports a new component and you accept it, add a rule in the same pull request:
The third rule has a path. It approves the component only in files under third_party/json/. If the same code turns up somewhere else, the scan still reports it.
scanoss-cli matches rules by PURL without the version. On its own, a rule for pkg:npm/vue@2.6.14 marks every version of vue as identified, including a later one with a different licence or a known vulnerability. The gate below closes that gap. When a rule names a version, the gate treats only that version as approved. Leave the version out only when you mean to approve every version.

Step 3: Handle matches that are wrong

Not every match is a component you use. Four rule types cover the common cases:
Paths in rules are relative to the scanned directory:
  • dir/ matches every file under dir, at any depth.
  • A glob, such as dir/*.c, matches with standard glob rules. * does not cross a /.
  • Any other value must match the file path exactly.
Every rule needs a purl. The rules run in this order: ignore, identify, the optional --ranking-threshold filter, remove, and replace.

Approve a baseline without editing scanoss.json

To approve everything in an earlier result for one run, pass it with -i, --identify. Each component in the file becomes an approval rule without a path:
--identify accepts a scanoss-cli raw result, a CycloneDX or SPDX file, or a component list ({"components":[{"purl":"..."}]}). -n, --ignore <file> works the same way for ignore rules. Both can be combined with scanoss.json. Use this to adopt SCANOSS on a large existing codebase. Keep baseline-results.json as a build artefact and fail only on what appears after it. For a reviewed, long-term record, prefer scanoss.json.

What the output means

In the raw result, an approved component carries "identified": true, both on the component and on the file evidence the rule covered:
A component approved only for some paths still shows "identified": true at component level. Check the identified value on each evidence entry to see which files the rule covered. In CycloneDX output, the component-level flag appears as the scanoss:identified property.

How it fails the pipeline

scanoss.json changes what the result contains, not the exit code. Your gate decides what fails. Save this filter in your repository as scanoss/unapproved.jq. The other recipes use it too. It prints each detected component that scanoss.json doesn’t approve:
scanoss/unapproved.jq
Run it after the scan. It fails with exit code 2 when it prints anything:
With the rules from Step 2, every version of zlib, lodash, and json passes. Change the lodash rule to pkg:npm/lodash@4.17.21 and only that version passes. An upgrade then fails the gate until someone approves the new version. To bootstrap pinned rules instead, use {purl: (if .version then .purl + "@" + .version else .purl end)} in place of {purl} in Step 1. The same file also controls which files scanoss-cli scans (settings.skip), and Crypto Finder reads its skip patterns too. See Scanning your project.
The settings.file_snippet keys skip_headers, skip_headers_limit, and ranking_threshold in scanoss.json override the matching command-line flags. If a flag seems to have no effect, check for these keys.