Andrew Mercer
on this page

Software Composition Analysis (SCA): A Complete Guide from Zero

This guide assumes you know nothing about Software Composition Analysis. By the end you should understand what SCA is, why organizations pay a lot of money for it, how the tools actually work under the hood, what the big commercial products (FossID, Black Duck, Flexera/Revenera Code Insight and others) do differently, and how to get real hands-on experience using free open-source tools.

A companion document, Software Bill of Materials (SBOM) Formats: SPDX and CycloneDX from Zero, covers the output formats that SCA tools produce and consume. The two topics are tightly linked — read both.


Table of Contents

  1. The problem SCA solves
  2. What SCA is (and is not)
  3. Core vocabulary you must know
  4. How SCA tools find components
  5. The knowledge base: the real product
  6. Security: matching components to vulnerabilities
  7. Licensing: the other half of SCA
  8. Policies, approvals, and exceptions
  9. The SCA workflow end to end
  10. Where SCA fits in the SDLC and CI/CD
  11. Commercial tools in depth
  12. Open-source SCA tooling
  13. Hands-on lab: build your own SCA pipeline
  14. Vulnerability triage: doing it properly
  15. Common pitfalls and how to avoid them
  16. Metrics and reporting
  17. Talking about SCA in an interview
  18. Glossary
  19. Further reading

1. The problem SCA solves

Almost no one writes software from scratch anymore. A modern application is a thin layer of code your team wrote sitting on top of a very large pile of code other people wrote: frameworks, libraries, language runtimes, operating system packages inside container images, code copied from Stack Overflow or GitHub, vendored third-party SDKs, and so on. Industry reports routinely find that the large majority of the code in a typical commercial codebase is open source.

That third-party code brings three kinds of risk.

Security risk. Every dependency can contain vulnerabilities. If you use a library, its bugs are your bugs. Two famous examples:

  • Equifax (2017) — attackers exploited a known vulnerability in Apache Struts, a Java web framework. A patch had been available for weeks; the affected component simply wasn't updated. Roughly 147 million people's personal data was exposed.
  • Log4Shell (December 2021, CVE-2021-44228) — a remote code execution flaw in Apache Log4j 2, a logging library used in an enormous number of Java applications. The hardest part for most organizations was not fixing it; it was finding out where they were using it, because Log4j was frequently a transitive dependency buried several layers deep.

Legal / license risk. Open source is free to use, but not free of conditions. Every open-source component comes with a license, and licenses impose obligations. Some only require you to keep a copyright notice. Others (copyleft licenses like the GPL) can require you to release your own source code under the same license if you distribute the combined work. Shipping a product that violates a license can lead to lawsuits, forced source disclosure, injunctions against shipping, or failed acquisitions when the problem surfaces during due diligence.

Operational / supply-chain risk. Components can be abandoned by their maintainers, become unmaintained forks, be hijacked (a malicious maintainer takes over a popular package), be impersonated (typosquatting: reqeusts instead of requests), or be deliberately backdoored. The 2024 xz-utils backdoor — a multi-year social engineering effort to plant a backdoor in a compression library used by OpenSSH on many Linux distributions — is the canonical example.

The central question SCA answers is:

"What third-party code is in our software, where did it come from, what license is it under, and is it vulnerable?"

If you can't answer that question quickly and accurately, you can't respond to the next Log4Shell, and you can't confidently ship a product.


2. What SCA is (and is not)

Software Composition Analysis is the practice — and the category of tools — that automatically identifies the open-source and third-party components in a codebase or build artifact, and then evaluates those components for security vulnerabilities, license obligations, and other risk factors.

An SCA tool typically does four things:

  1. Inventory — discover every component (name, version, origin) and how they relate to each other.
  2. Enrich — look each component up in a knowledge base to get its license(s), known vulnerabilities, latest version, and other metadata.
  3. Evaluate — apply your organization's policies ("no AGPL in shipped products", "fail the build on any critical vulnerability with a known exploit").
  4. Report — produce dashboards, tickets, compliance reports, attribution/notice files, and Software Bills of Materials (SBOMs).

How SCA differs from other security testing

People often confuse the AppSec acronyms. Here's how they differ:

Technique What it analyzes What it finds Example tools
SCA (Software Composition Analysis) Third-party components you use Known vulnerabilities (CVEs) in dependencies, license issues, outdated/abandoned packages Black Duck, FossID, Code Insight, Snyk Open Source, Mend, Dependency-Track, Trivy
SAST (Static Application Security Testing) Source code you wrote Bugs in your own code: SQL injection, XSS, unsafe deserialization Semgrep, SonarQube, Checkmarx, CodeQL
DAST (Dynamic Application Security Testing) A running application, from outside Exploitable behaviour: injection, misconfigurations, auth flaws OWASP ZAP, Burp Suite
IAST / RASP A running app, instrumented from inside Vulnerabilities observed during real execution Contrast Security
Secret scanning Source and history Leaked API keys, passwords, tokens gitleaks, trufflehog
Container scanning Container images Vulnerable OS packages and app dependencies inside images Trivy, Grype, Clair — this is really SCA applied to images
IaC scanning Terraform, Helm, K8s manifests Insecure infrastructure config Checkov, tfsec/Trivy, KICS

The key distinction: SAST finds new, unknown bugs in your code. SCA finds known, already-published problems in other people's code that you've pulled in. SCA is fundamentally a matching problem: identify the component precisely, then match it against databases of known issues.


3. Core vocabulary you must know

You'll hear these terms constantly. Learn them before anything else.

Component — Any discrete unit of third-party software: a library (lodash), a framework (Spring Boot), an OS package (openssl from Debian), a vendored source folder, a binary DLL, a single copied file, or even a copied snippet of code.

Direct dependency — A component your project declares explicitly (it's in your package.json, Cargo.toml, pom.xml, requirements.txt).

Transitive (indirect) dependency — A dependency of a dependency. You declare A; A depends on B; B depends on C. B and C are transitive. Most of your dependency tree is usually transitive, and most surprises live there. Log4Shell was devastating precisely because Log4j was so often transitive.

Dependency tree / graph — The full structure of who depends on whom. Good SCA tools show the path from your code to a vulnerable component, because that tells you which direct dependency to upgrade.

Manifest — The file where you declare dependencies, often with version ranges ("express": "^4.18.0").

Lockfile — A file recording the exact resolved versions of every dependency, direct and transitive (package-lock.json, Cargo.lock, poetry.lock, go.sum, Gemfile.lock). Lockfiles are the single most valuable input to an SCA tool because they remove ambiguity.

Package manager / ecosystem — npm, PyPI/pip, Maven/Gradle, NuGet, Cargo, Go modules, RubyGems, Composer, CocoaPods, plus OS-level managers like dpkg/apt, rpm/dnf, apk.

CVE (Common Vulnerabilities and Exposures) — A unique ID for a publicly disclosed vulnerability, e.g. CVE-2021-44228. The CVE program is run by MITRE with many CVE Numbering Authorities (CNAs).

NVD (National Vulnerability Database) — The US NIST database that enriches CVEs with severity scores and CPE identifiers describing which products are affected.

CVSS (Common Vulnerability Scoring System) — A 0.0–10.0 severity score (None/Low/Medium/High/Critical). Versions 3.1 and 4.0 are in use. CVSS measures theoretical severity, not the likelihood you'll actually be attacked.

EPSS (Exploit Prediction Scoring System) — A probability (0–1) published by FIRST estimating how likely a CVE is to be exploited in the wild in the next 30 days. Complements CVSS.

CISA KEV (Known Exploited Vulnerabilities catalog) — A US government list of CVEs confirmed to be exploited in the wild. If something is on KEV, prioritize it.

GHSA / OSV — The GitHub Security Advisory database and the OSV (Open Source Vulnerabilities) format/database. These are ecosystem-native advisory sources that describe affected package versions directly, which is often more accurate for open-source libraries than NVD's CPE data.

CPE (Common Platform Enumeration) — A naming scheme used by NVD, e.g. cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*. Designed for products, not packages, so it maps poorly to library ecosystems.

purl (Package URL) — The de facto standard identifier for software packages, e.g. pkg:maven/org.apache.logging.log4j/[email protected] or pkg:cargo/[email protected]. It encodes ecosystem, namespace, name, and version precisely. Modern SCA tools and both major SBOM formats use purl heavily.

License — The legal terms under which a component may be used, modified, and distributed.

Declared license — The license the component's author says it's under (in metadata like package.json's license field).

Detected / observed license — License text or headers actually found in the files. These frequently disagree with the declared license.

Concluded license — The license your organization (or tool) has decided actually applies after reviewing the evidence.

Copyleft — Licenses that require derivative works to be distributed under the same license (GPL, AGPL, and weaker variants like LGPL, MPL, EPL).

Permissive — Licenses with minimal obligations, usually attribution only (MIT, BSD, Apache-2.0, ISC).

Attribution / NOTICE file — A document shipped with your product listing third-party components, their licenses, and copyright notices, as many licenses require.

Snippet — A fragment of code (a function, a block) copied from a third-party source into your own files. Snippets carry the original license even though no package manager knows about them.

Policy — An organization-defined rule that turns findings into decisions: allow, warn, block, require review.

False positive — A finding that isn't real: wrong component identification, wrong version, or a vulnerability that doesn't apply.

False negative — A real problem the tool missed. More dangerous than false positives because it's invisible.

Reachability — Whether your code actually calls the vulnerable function in a dependency. A vulnerable library that's present but whose vulnerable code path is never invoked is lower risk.

VEX (Vulnerability Exploitability eXchange) — A machine-readable statement of whether a product is actually affected by a given vulnerability (e.g. "not affected — vulnerable code not present"). Covered in detail in the SBOM guide.

SBOM (Software Bill of Materials) — A formal, machine-readable inventory of components. The primary output artifact of SCA. Formats: SPDX and CycloneDX.


4. How SCA tools find components

This is the most important technical section. Tools differ enormously in how they discover components, and that determines what they can and can't see. There are roughly six techniques, and the best tools combine several.

4.1 Manifest and lockfile parsing

The simplest and most common approach. The tool reads package-lock.json, Cargo.lock, pom.xml, requirements.txt, go.sum, etc., and extracts names and versions.

  • Strengths: fast, cheap, no build required, precise when a lockfile exists.
  • Weaknesses: only sees what the package manager knows about. Misses vendored code, copied files, snippets, binaries, and anything installed outside a package manager (a curl | tar in a Dockerfile). Manifest-only scanning without a lockfile may guess versions from ranges and be wrong.

Example: from this Cargo.lock fragment a tool can produce an exact component pkg:cargo/[email protected]:

[[package]]
name = "serde"
version = "1.0.210"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a"

4.2 Build-time dependency resolution

Instead of parsing files statically, the tool runs (or hooks into) the actual package manager or build tool — mvn dependency:tree, gradle dependencies, npm ls, cargo metadata, dotnet list package --include-transitive — to get the resolved graph as the build actually sees it.

  • Strengths: most accurate dependency graph, including scopes (compile vs test vs dev), profiles, and conditional dependencies.
  • Weaknesses: needs a working build environment, credentials for private registries, and the right toolchain versions. Slower. Black Duck's "Detect" calls these detectors; many enterprise rollouts spend most of their effort getting builds to run inside the scanner.

Dev/test scope matters. A vulnerable test-only dependency (e.g. a mocking library) never ships to customers. Good tools let you exclude or de-prioritize non-production scopes.

4.3 File signature (hash) matching

The tool computes cryptographic hashes (SHA-1, SHA-256, etc.) of every file in a directory and compares them to a knowledge base of hashes of known open-source files. If vendor/jquery.min.js has a hash identical to jQuery 3.5.1's distributed file, it's identified as jQuery 3.5.1, no manifest required.

Variants include hashing whole directories (directory signatures) to recognize an entire vendored library even if a few files were changed.

  • Strengths: finds vendored and copied components that no package manager knows about.
  • Weaknesses: an exact hash breaks with a single changed byte (reformatting, line endings, a local patch). Requires a huge knowledge base of file hashes.

4.4 Snippet matching

The most sophisticated (and most expensive) technique, and the specialty of tools like FossID, Black Duck snippet scanning, and SCANOSS. The tool breaks your source files into normalized fragments — often by stripping whitespace and comments, tokenizing, and computing rolling fingerprints over small windows (a technique related to the "winnowing" algorithm used in plagiarism detection) — and searches for those fragments across a knowledge base built from billions of open-source files.

This catches a developer who pasted a 40-line function from a GPL project into your proprietary codebase, even after renaming variables lightly.

  • Strengths: finds copy-pasted code, partial copies, modified copies. Essential for license compliance audits (M&A due diligence, preparing a product for distribution) because copied snippets are invisible to every other technique.
  • Weaknesses: generates a lot of matches that require human review ("identification"). Common boilerplate (getters/setters, standard algorithms, auto-generated code) matches thousands of projects. Snippet scanning is a workflow, not a button: someone has to triage matches and decide what's real.

4.5 Binary analysis

Analyzing compiled artifacts — executables, shared libraries, firmware images, JARs, DLLs, mobile apps — when you don't have source. Techniques include extracting embedded version strings, symbol tables, string constants, and code fingerprints from compiled functions. Black Duck's Binary Analysis (formerly Protecode) is a well-known example; firmware analysis tools in the embedded space also do this.

  • Strengths: works on vendor-supplied binaries, firmware, and final shipped artifacts (you scan what you ship, not what you think you ship).
  • Weaknesses: less precise; statically linked or stripped binaries are hard; compiler optimizations obscure fingerprints.

Rust and Go note: both statically link dependencies into a single binary. cargo-auditable embeds the dependency list into Rust binaries so tools like Trivy, Grype, and Syft can recover it later; Go embeds module info by default (go version -m <binary>).

4.6 Container image and OS package analysis

For container images, the tool unpacks image layers and reads the OS package databases (/var/lib/dpkg/status for Debian/Ubuntu, /var/lib/rpm for RHEL/Fedora, /lib/apk/db/installed for Alpine), then also scans application files within the image using the techniques above. This is what Trivy, Grype/Syft, Clair, and the container modules of commercial tools do.

A distroless or scratch-based image with a statically linked binary has very little for this technique to find — which is good for attack surface but means you rely on binary techniques or embedded metadata.

4.7 Comparison of detection techniques

Technique Finds packaged deps Finds vendored code Finds snippets Needs source Needs build Review effort
Manifest/lockfile ✅ ❌ ❌ Partial ❌ Low
Build resolution ✅ (best graph) ❌ ❌ ✅ ✅ Low
File hash ✅ ✅ (unmodified) ❌ ❌ ❌ Low–Med
Snippet ✅ ✅ (modified too) ✅ ✅ ❌ High
Binary ✅ ✅ ❌ ❌ ❌ Medium
Container/OS ✅ (OS pkgs) Partial ❌ ❌ ❌ Low

Rule of thumb: dependency-based tools (Snyk, Dependabot, Trivy, Mend) are optimized for developer-speed security — fast feedback on known vulnerable packages. Deep-scan tools (FossID, Black Duck with snippet/signature scanning, Code Insight) are optimized for audit-grade completeness, especially for licensing, and accept higher review effort to get there.


5. The knowledge base: the real product

When you buy a commercial SCA tool, the scanner is the cheap part. The expensive, differentiating part is the knowledge base (KB) — the curated database the tool matches against. A KB typically contains:

  • Component catalogue — millions of open-source projects and their versions, mapped across ecosystems and forks.
  • File and snippet fingerprints — hashes and fragment fingerprints for billions of files, crawled from GitHub, GitLab, package registries, SourceForge, distro archives, and so on.
  • License data — declared licenses per version, plus license text recognition, and often curated corrections where metadata is wrong.
  • Vulnerability data — CVEs from NVD plus vendor-researched advisories. Black Duck publishes its own BDSA (Black Duck Security Advisories), which often appear before or without an NVD entry, and include more precise affected-version ranges.
  • Operational metadata — release dates, commit activity, number of contributors, whether the project looks abandoned.

Why the vulnerability data source matters

There are two broad styles of vulnerability matching:

  1. CPE-based (NVD-style): match the component to a CPE string, then look up CVEs listed against that CPE. CPEs describe products (apache:log4j), not packages (org.apache.logging.log4j:log4j-core on Maven Central vs log4j-api vs a shaded copy). This leads to false positives (the CVE gets reported against every artifact from the vendor) and false negatives (no CPE assigned). NVD has also had a significant analysis backlog since early 2024, meaning many recent CVEs lack the CPE enrichment that CPE-based tools rely on.

  2. Package-native (OSV/GHSA-style): advisories that state "package pkg:maven/org.apache.logging.log4j/log4j-core, versions >=2.0-beta9, <2.15.0 are affected." Much more precise for libraries. OSV.dev aggregates many ecosystem databases (GitHub, PyPA, RustSec, Go, npm, distro trackers).

Good tools combine both and add their own research. When evaluating a tool, ask: where does your vulnerability data come from, how fast is it updated, and how do you map it to packages?


6. Security: matching components to vulnerabilities

Once a component is identified, the security side works like this:

  1. Identify precisely — ecosystem, name, exact version (purl).
  2. Match — find advisories whose affected-version ranges include that version.
  3. Score — attach CVSS severity, EPSS probability, KEV status, exploit maturity.
  4. Locate — show the dependency path(s) from your project to the vulnerable component.
  5. Advise — recommend the minimum safe upgrade (ideally the smallest version change on the direct dependency that pulls in a fixed transitive version).
  6. Track — monitor continuously. A component that was clean yesterday can have a CVE published today. This is why SCA is not a one-time scan; mature tools re-evaluate stored inventories (or SBOMs) against new vulnerability data without rescanning code.

Version ranges are tricky

Each ecosystem has its own version semantics: SemVer for npm/Cargo, Maven's own ordering rules, PEP 440 for Python, Debian epoch/upstream/revision (1:3.0.11-1~deb12u2), RPM's EVR. A tool that compares Debian versions with SemVer rules will be wrong. Distro packages are a classic trap: Debian or Red Hat often backport a security fix into an old upstream version number. Upstream says "fixed in 3.0.13"; the distro's 3.0.11-1~deb12u2 is also fixed. Tools must use distro security trackers, not upstream ranges, for OS packages.

Reachability analysis

Some tools (Snyk, Endor Labs, Semgrep Supply Chain, and features in several commercial suites) perform reachability analysis: build a call graph from your code into dependencies to determine whether the vulnerable function is actually invoked. This can cut actionable findings dramatically, but it's an approximation — reflection, dynamic dispatch, and plugin loading can defeat it. Treat "unreachable" as "lower priority," not "safe forever."


7. Licensing: the other half of SCA

Security gets the headlines; licensing is where commercial tools like FossID, Black Duck, and Code Insight historically came from. License compliance was the original reason SCA existed.

Disclaimer: This section explains concepts. It is not legal advice. Organizations rely on their legal counsel for license interpretation; SCA tools supply evidence to support those decisions.

7.1 Why licenses matter

Copyright law gives the author exclusive rights. An open-source license is the permission to use, modify, and distribute — on conditions. Break the conditions and you may lose the permission, which means you're infringing copyright.

7.2 License categories

Category Typical examples Core obligation (simplified) Typical commercial risk
Public domain-like CC0-1.0, Unlicense, 0BSD Essentially none Very low
Permissive MIT, BSD-2-Clause, BSD-3-Clause, ISC, Apache-2.0, Zlib Keep copyright/license notices; Apache-2.0 adds NOTICE file handling and a patent grant/termination clause Low
Weak copyleft LGPL-2.1, LGPL-3.0, MPL-2.0, EPL-2.0, CDDL-1.0 Modifications to the component itself must be shared under the same license; your separate code generally needn't be (rules differ: LGPL is about linking/replaceability, MPL is file-level) Medium — manageable with care
Strong copyleft GPL-2.0, GPL-3.0 If you distribute a derivative/combined work, the whole work must be offered under the GPL with source High for proprietary distributed products
Network copyleft AGPL-3.0 Like GPL, but triggered by providing the software over a network, not just distribution Very high for SaaS
Source-available / non-OSI SSPL-1.0, BUSL-1.1 (Business Source License), Elastic License 2.0, Commons Clause add-ons Restrictions on use (e.g. no competing hosted service) — not open source by OSI definition Varies; often banned by policy
Non-software / content CC-BY-4.0, CC-BY-SA-4.0, CC-BY-NC Attribution; share-alike; NC = non-commercial only NC is a problem for any commercial use
No license (nothing found) Default copyright applies: you have no right to use it High — treat as unknown
Commercial / proprietary Vendor EULAs Whatever the contract says Contract-dependent

7.3 Key licensing concepts

Distribution is usually the trigger. For GPL-family licenses, most obligations kick in when you distribute software (ship a binary, a device, an installer, a container image to customers). Internal-only use typically doesn't trigger GPL source obligations — but AGPL can be triggered by network use. This is why the same component can be "fine" for an internal tool and "blocked" for a shipped product.

Linking and combination. Whether using a library creates a "derivative work" depends on how it's combined (static linking, dynamic linking, separate process, network call). The LGPL explicitly permits dynamic linking from proprietary code if users can replace the library. These questions are legally nuanced, which is why policies often simplify: "GPL = needs legal review."

License expressions. Components can have multiple licenses. SPDX expression syntax captures this precisely:

  • MIT OR Apache-2.0 — disjunctive: you choose either (very common in the Rust ecosystem).
  • GPL-2.0-only AND BSD-3-Clause — conjunctive: both apply (different files under different licenses).
  • GPL-2.0-only WITH Classpath-exception-2.0 — a license with an exception that relaxes it (used by OpenJDK).
  • GPL-2.0-only vs GPL-2.0-or-later — whether later versions of the GPL may be chosen. Matters a lot.
  • LicenseRef-acme-proprietary — a custom license not on the SPDX list.

License compatibility. Some licenses can't be combined in one distributed work. Classic example: GPL-2.0-only code cannot be combined with Apache-2.0 code in a distributed derivative (the FSF considers them incompatible), while GPL-3.0 is compatible with Apache-2.0.

Declared vs detected discrepancies. A package's metadata says MIT, but a file inside carries a GPL header, or the repo's LICENSE file was changed between versions. Deep-scan tools surface these conflicts; dependency-only tools usually trust the metadata.

License changes over time. Projects relicense. Elasticsearch and Kibana moved from Apache-2.0 to SSPL/Elastic License in 2021 (and later added AGPL as an option); HashiCorp moved Terraform and other products from MPL-2.0 to BUSL-1.1 in 2023, which prompted the OpenTofu fork; Redis changed licensing in 2024 and later added AGPL as an option. The version you use determines the license, which is why SCA tracks license per version, not per project.

Copyright notices. Permissive licenses still require preserving copyright notices. Deep-scan tools extract copyright statements from file headers so you can generate accurate attribution reports.

7.4 Compliance deliverables

Licensing work produces concrete artifacts:

  • Third-party notices / attribution report — list of components, versions, licenses, copyright holders, and full license texts. Shipped in an "About" screen, a THIRD-PARTY-NOTICES.txt, or product documentation.
  • Source code offer / corresponding source package — for GPL/LGPL components in distributed products (common in embedded devices and appliances).
  • SBOM — increasingly requested by customers and regulators.
  • Audit report — for M&A due diligence, a full inventory with risk ratings.

8. Policies, approvals, and exceptions

Raw findings are noise until you apply policy. Every serious SCA tool has a policy engine. Typical rules:

License policies - Allow: MIT, BSD-, Apache-2.0, ISC, Zlib, CC0, Unlicense - Require review: LGPL-, MPL-2.0, EPL-, any LicenseRef-*, unknown licenses - Deny for distributed products: GPL-, AGPL-, SSPL, CC-BY-NC- - Deny everywhere: no license found

Security policies - Block merge/release: Critical CVSS, or any CVE on CISA KEV - Warn: High severity with available fix - Ignore: dev/test-scope only, with justification

Operational policies - Warn on components with no release in 3+ years - Block components from unapproved registries - Block known-malicious packages

Policy context matters. Mature setups use different policy profiles per distribution model: internal tool, SaaS, on-prem shipped product, embedded firmware, mobile app. The same AGPL component is a blocker for a SaaS product and possibly irrelevant to a build-only CI utility.

Exceptions (waivers). Real life requires exceptions. A good process records who approved, why, for which version (not all future versions), and until when (expiry date). Unbounded exceptions are how organizations end up with 5-year-old "temporary" waivers on critical vulnerabilities.

Component approval workflows. Some organizations require pre-approval before a new open-source component is introduced (an "intake" request). Tools like Code Insight and Black Duck support request/approval workflows; Sonatype and JFrog support repository-level "firewalls" that block disallowed components from even being downloaded.


9. The SCA workflow end to end

Here's the lifecycle in a mature organization:

 ┌──────────┐   ┌──────────┐   ┌──────────────┐   ┌───────────┐   ┌────────────┐   ┌──────────┐
 │  1. Scan  │──▶│ 2. Identify│──▶│ 3. Evaluate  │──▶│ 4. Triage │──▶│ 5. Remediate│──▶│ 6. Report│
 │ (collect) │   │ (confirm)  │   │ (policy)     │   │ (decide)  │   │ (fix/waive) │   │ (SBOM,   │
 └──────────┘   └──────────┘   └──────────────┘   └───────────┘   └────────────┘   │ notices) │
       ▲                                                                            └────┬─────┘
       │                       7. Monitor continuously (new CVEs vs stored inventory)    │
       └─────────────────────────────────────────────────────────────────────────────────┘
  1. Scan — run the scanner on source, build output, or images. Configure scopes, exclusions (e.g. node_modules of test fixtures), and which detection techniques to use.
  2. Identify — for dependency scans, mostly automatic. For signature/snippet scans, a reviewer works the identification queue: for each match, decide "this is third-party component X at version Y," "this is our original code," or "false match — boilerplate." FossID, Black Duck, and Code Insight all have this concept; it's the most labour-intensive part of audit-grade scanning, and it's where experience matters most.
  3. Evaluate — the policy engine flags violations.
  4. Triage — humans prioritize security findings (see Section 14) and route license issues to legal/OSPO.
  5. Remediate — upgrade, replace the component, remove the code, rewrite the snippet, isolate it (e.g. separate process), obtain a commercial license, or record an approved exception.
  6. Report — SBOMs, attribution notices, compliance reports, risk dashboards.
  7. Monitor — continuous re-evaluation of every released version's inventory against new vulnerability data, with alerts.

Who's involved

  • Developers — fix dependency issues, mostly via upgrades.
  • AppSec / Product Security — owns vulnerability triage, VEX statements, policy.
  • OSPO (Open Source Program Office) and Legal — own license policy and rulings.
  • DevOps / Platform Engineering — integrates scanners into CI/CD, registries, and image builds; manages the tool infrastructure. This is usually where a DevOps engineer meets SCA.
  • Release / Compliance — ensures every shipped release has an SBOM and notices.

10. Where SCA fits in the SDLC and CI/CD

"Shift left" means catching issues as early as possible. SCA can run at many points:

Stage What runs Purpose
IDE Plugins (Snyk, Black Duck Code Sight, Mend, etc.) Warn as the developer adds a dependency
Pre-commit / pre-push Lightweight lockfile checks (cargo deny, npm audit, osv-scanner) Stop obviously bad changes before they're shared
Pull/merge request Dependency scan + diff ("this MR introduces 2 new components, 1 with a High CVE") Main developer feedback loop
Artifact repository Sonatype Repository Firewall, JFrog Curation/Xray Block malicious or policy-violating packages at download time
CI build (main branch) Full scan, SBOM generation Record of what was built
Container build Image scan + SBOM attestation Covers OS packages and app layers
Release gate Policy check; deep scan for distributed products Don't ship violations
Registry / runtime Continuous rescans of stored images/SBOMs Catch newly disclosed CVEs in deployed software

Example: GitLab CI with Trivy (free) for dependency + SBOM

stages: [test, sca]

variables:
  TRIVY_NO_PROGRESS: "true"
  TRIVY_CACHE_DIR: ".trivycache/"

sca:dependencies:
  stage: sca
  image:
    name: aquasec/trivy:latest
    entrypoint: [""]
  script:
    # Human-readable table in the job log
    - trivy fs --scanners vuln,license --severity HIGH,CRITICAL .
    # SBOM artifact (CycloneDX) for downstream tools like Dependency-Track
    - trivy fs --format cyclonedx --output gl-sbom-app.cdx.json .
    # Gate: fail the job on CRITICAL vulnerabilities that have a fix available
    - trivy fs --exit-code 1 --severity CRITICAL --ignore-unfixed .
  cache:
    paths: [.trivycache/]
  artifacts:
    when: always
    paths: [gl-sbom-app.cdx.json]
    reports:
      cyclonedx: [gl-sbom-app.cdx.json]

Example: Black Duck Detect in a pipeline (illustrative)

Black Duck's CI integration is a launcher called Detect that runs package-manager detectors, signature scanning, and optionally binary scanning, then uploads results to the Black Duck server. Script URLs and major versions change over time, so check current documentation, but invocations look like this:

bash <(curl -s -L https://detect.blackduck.com/detect10.sh) \
  --blackduck.url="$BLACKDUCK_URL" \
  --blackduck.api.token="$BLACKDUCK_API_TOKEN" \
  --detect.project.name="my-service" \
  --detect.project.version.name="$CI_COMMIT_REF_NAME" \
  --detect.tools=DETECTOR,SIGNATURE_SCAN \
  --detect.policy.check.fail.on.severities=BLOCKER,CRITICAL

Key ideas: a project and project version in Black Duck correspond to your application and its branch/release; the policy check makes the CI job fail when a policy violation of the listed severity exists.

CI design advice

  • Don't block everything on day one. Turning on a hard gate against an existing codebase with hundreds of findings will get the gate disabled within a week. Start in report-only mode, baseline, then block only new violations or a narrow, high-confidence set (critical + KEV + fix available).
  • Separate fast and deep scans. Fast dependency scans on every MR; deep signature/snippet scans nightly or at release.
  • Cache vulnerability databases to avoid rate limits and slow jobs.
  • Store SBOMs as build artifacts and push them to a central platform for continuous monitoring.
  • Handle private registries. Build-resolution scanning needs the same credentials as the build.

11. Commercial tools in depth

Job postings often name a few specific tools. Experience with any one transfers well to the others because the concepts — scan, identify, policy, triage, report — are identical. Here's what distinguishes the ones you'll see most.

Vendor product names, ownership, and packaging change frequently through acquisitions and rebrands. Verify current details on vendor sites before relying on specifics.

11.1 FossID

What it is: A Swedish SCA vendor specializing in deep source code scanning — file and snippet-level matching against a very large knowledge base of open-source code. Its main product is FossID Workbench, a server application with a web UI for scanning and reviewing results, plus CLI/API tooling for automation.

Where it shines: - License compliance and audits where you must find copied code, not just declared dependencies — embedded/automotive software, products being distributed to customers, M&A due diligence. - Detecting partial and modified copies of open-source files inside proprietary source trees. - Workflows where source code must not leave the premises: FossID supports a "blind" scanning approach in which only fingerprints, rather than source, are sent for matching.

Typical workflow: 1. Create a project and scan (upload or point at source, often via CI or API). 2. Workbench produces matches: files and snippets matching known open-source components. 3. Reviewers work through pending identifications — confirming a match as a specific component/version/license, marking it as original code, or dismissing it. Identifications can be propagated across similar files and reused in later scans so you don't redo work. 4. Licenses and copyrights are extracted and associated with identified components. 5. Generate reports and SBOMs (SPDX/CycloneDX).

What experience with it looks like: running scans via API/CI, tuning scan settings to reduce noise, performing and reviewing identifications, resolving license conflicts with legal, generating compliance reports and SBOMs.

11.2 Black Duck

History: Black Duck Software was one of the earliest open-source compliance companies. Synopsys acquired it in 2017 and folded it into its Software Integrity Group; in 2024 that group was sold to private equity and relaunched as an independent company named Black Duck Software. You'll see "Synopsys Black Duck" in older docs and job descriptions.

Main components: - Black Duck SCA (formerly "Black Duck Hub") — the central server: projects, versions, BOM view, policy management, vulnerability and license data, reports, SBOM export. - Detect — the scanning client/CI launcher (package-manager detectors, signature scanner, snippet scanning, binary scanning, container scanning). - KnowledgeBase — the component/license/vulnerability database, plus BDSA advisories from Black Duck's own research team. - Binary Analysis — scanning compiled artifacts and firmware. - IDE integrations and integrations with Jira, Jenkins, GitLab, GitHub, Azure DevOps, Artifactory, etc.

Where it shines: large enterprises wanting a single platform for both security and license compliance, multiple scanning techniques (dependency + signature + snippet + binary), strong audit/M&A reputation, rich policy and reporting.

Key concepts you'll encounter: - BOM (in Black Duck's UI, the component list for a project version) with match types: direct dependency, transitive, exact file match, file-level signature, snippet, binary. - Remediation status per vulnerability (new, needs review, patched, mitigated, ignored, remediation required) — effectively VEX-like triage state. - Policy rules with severities (Blocker, Critical, Major, Minor, Trivial), used for CI gating. - Component adjustments — manually adding, ignoring, or correcting components and licenses when the scan is wrong.

11.3 Flexera / Revenera Code Insight

History: Flexera's SCA product was FlexNet Code Insight (it came from Flexera's acquisition of Palamida). Flexera reorganized its supplier-facing products under the Revenera brand, so you'll see it as Revenera Code Insight today. Flexera itself is better known for software asset management and license entitlement (FlexNet Manager); the Code Insight lineage is the SCA product.

Where it shines: open-source license compliance programs with strong workflow and governance: component request/approval processes, legal review workflows, inventory management, and reporting, alongside vulnerability data. Popular with organizations that run formal OSPO processes.

Key concepts: - Projects and inventory items — each identified component in a project is an inventory item with license, vulnerabilities, and review status. - Scan profiles and remote scanning agents that scan source in your environment. - Policy profiles that automatically approve or reject inventory based on license/vulnerability. - Request workflows where developers request approval to use a component before adoption. - Reports including notices/attribution and SBOM exports.

11.4 Other tools you'll see in job postings

Tool Positioning Notes
Snyk Open Source Developer-first dependency SCA Strong IDE/PR integration, fix PRs, reachability for some languages
Mend.io (formerly WhiteSource) Enterprise SCA + automated remediation Owns Renovate, the popular dependency-update bot
Sonatype Lifecycle / Nexus IQ / Repository Firewall SCA + repository governance Deep Maven heritage (Sonatype runs Maven Central); firewall blocks bad packages at download
JFrog Xray / Curation SCA built into Artifactory Scans artifacts in the binary repository
FOSSA License compliance + security, developer-friendly Popular with startups and OSS-heavy companies
Checkmarx SCA, Veracode SCA, Synopsys/Black Duck Polaris SCA bundled in AppSec platforms Often bought alongside SAST
GitHub Dependabot / Dependency Review Built into GitHub Alerts and automatic upgrade PRs using GitHub Advisory Database
GitLab Dependency Scanning / License Scanning Built into GitLab Ultimate Uses Trivy/Gemnasium-style analyzers; SBOM reports
SCANOSS Open-source snippet-matching platform and knowledge base Open alternative in the snippet space
Endor Labs, Semgrep Supply Chain Newer, reachability-focused Emphasize reducing noise

11.5 How to choose (what buyers evaluate)

  • Detection depth required: dependency-only vs signature/snippet/binary.
  • Ecosystem coverage: languages, package managers, C/C++ (notoriously hard — no universal package manager), containers, firmware.
  • Data quality: KB size, vulnerability research, license curation, update speed.
  • Noise level: false positives cost engineering time; reachability and good identification matter.
  • Workflow: policy engine, approvals, exceptions with expiry, Jira integration.
  • Deployment: SaaS vs on-premises (some industries require on-prem), data residency, whether source leaves the network.
  • Outputs: SPDX/CycloneDX export and import, VEX support, notices generation, API quality.
  • Cost model: per developer, per project, per scan volume.

12. Open-source SCA tooling

You don't need a commercial license to learn SCA. These free tools cover most concepts:

Tool What it does
Syft (Anchore) Generates SBOMs (SPDX, CycloneDX) from directories, archives, container images
Grype (Anchore) Vulnerability scanner that consumes images, directories, or SBOMs
Trivy (Aqua Security) All-in-one: vulnerabilities, licenses, secrets, IaC misconfigs, SBOM generation, for filesystems, repos, images, Kubernetes
OSV-Scanner (Google) Scans lockfiles/SBOMs/directories against OSV.dev
OWASP Dependency-Track A platform: ingests SBOMs, continuously monitors them for new vulnerabilities, policy engine, license tracking, portfolio dashboards, VEX/triage, API — the closest free analogue to a commercial SCA server
OWASP Dependency-Check Older Java-centric CPE-based scanner
ScanCode Toolkit (AboutCode) Deep license, copyright, and package detection in source files — the reference open-source license scanner
ScanCode.io Web/pipeline wrapper around ScanCode for scanning codebases and images
ORT (OSS Review Toolkit) End-to-end open-source compliance pipeline: analyze dependencies, download sources, scan licenses, evaluate policy rules, generate notices and SBOMs. Used by many large companies
cdxgen (CycloneDX) Multi-language CycloneDX SBOM generator
cargo-audit / cargo-deny Rust: RustSec advisory checks; cargo-deny adds license allow/deny lists, banned crates, source restrictions
npm audit, pip-audit, govulncheck Ecosystem-native auditors; govulncheck includes call-graph reachability for Go
Renovate / Dependabot Automated dependency update PRs — the remediation half of SCA

ORT + ScanCode + Dependency-Track together approximate what an enterprise suite does: inventory, license scanning, policy evaluation, notices, SBOM, continuous monitoring. Snippet matching is the main capability that's hard to reproduce for free at scale (SCANOSS is the notable open option).


13. Hands-on lab: build your own SCA pipeline

This lab gives you genuine hands-on experience with every SCA concept. Use any Linux machine with Docker.

13.1 Install the tools

# Syft and Grype (Anchore install scripts install to ./bin or a path you choose)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b ~/.local/bin
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b ~/.local/bin

# Trivy — or use the container image aquasec/trivy
# See https://trivy.dev for distro packages

# ScanCode Toolkit via pip (in a virtualenv)
python3 -m venv ~/venvs/scancode && . ~/venvs/scancode/bin/activate
pip install scancode-toolkit

13.2 Create a deliberately vulnerable project

mkdir -p ~/sca-lab/vuln-app && cd ~/sca-lab/vuln-app
cat > requirements.txt <<'EOF'
requests==2.19.0
PyYAML==5.3
Jinja2==2.10
EOF

These are old versions with well-known CVEs.

13.3 Inventory: generate an SBOM

syft dir:. -o table
syft dir:. -o cyclonedx-json=sbom.cdx.json -o spdx-json=sbom.spdx.json

Notice: Syft found only the three direct packages, because a bare requirements.txt with no lockfile and no installed environment carries no transitive information. That's a lesson in itself — lockfiles and build resolution matter. Try installing into a virtualenv and scanning the environment, and compare the counts.

13.4 Vulnerabilities: scan the SBOM

grype sbom:./sbom.cdx.json
trivy sbom sbom.cdx.json

Compare the outputs. They'll mostly agree but not perfectly — different vulnerability databases and matching logic. Investigating why they differ is excellent practice.

13.5 Containers: OS packages + app dependencies

trivy image python:3.8-slim
syft python:3.8-slim -o table | head -40
grype python:3.8-slim --only-fixed

Look at how many findings come from Debian OS packages versus Python packages, and how --only-fixed / --ignore-unfixed changes things.

mkdir -p ~/sca-lab/licenses && cd ~/sca-lab/licenses
pip download --no-deps --no-binary :all: requests==2.31.0
tar xzf requests-2.31.0.tar.gz
scancode --license --copyright --package --json-pp scan.json --html scan.html requests-2.31.0/

Open scan.html. You'll see per-file license detections, copyright holders, and the declared package license — the same evidence commercial tools present for identification.

Then simulate a snippet problem: paste a function with a GPL header into a file in your own project and rescan. ScanCode detects the license header; it would not detect the copied code if you stripped the header — which is exactly the gap snippet scanners like FossID and Black Duck fill.

13.7 Policy: cargo-deny for a Rust project

cargo install cargo-deny
cd your-rust-project
cargo deny init     # creates deny.toml

Edit deny.toml:

[licenses]
allow = ["MIT", "Apache-2.0", "BSD-3-Clause", "ISC", "Unicode-3.0"]
confidence-threshold = 0.9

[bans]
multiple-versions = "warn"

[advisories]
# RustSec advisory database is used by default
cargo deny check licenses advisories bans sources

This is a policy engine in miniature: allow-listed licenses, banned crates, allowed registries, vulnerability advisories.

13.8 Continuous monitoring: Dependency-Track

Dependency-Track ships Docker Compose files in its documentation. Once it's running:

  1. Log in, create a project (e.g. vuln-app, version 1.0.0).
  2. Create an API key for a team with BOM_UPLOAD permission.
  3. Upload the SBOM:
curl -X POST "http://localhost:8081/api/v1/bom" \
  -H "X-Api-Key: $DT_API_KEY" \
  -F "projectName=vuln-app" \
  -F "projectVersion=1.0.0" \
  -F "autoCreate=true" \
  -F "[email protected]"
  1. Explore: components, vulnerabilities, the audit/analysis workflow (mark findings Not Affected, False Positive, Exploitable, with justifications), policies (license groups, severity conditions), and notifications.

Dependency-Track's analysis states map directly onto VEX concepts and onto the remediation statuses in commercial tools — practising here transfers directly.

13.9 Wire it into CI

Take the GitLab CI example from Section 10, add a job that uploads the SBOM to Dependency-Track, and gate merges on critical, fixable vulnerabilities. You now have a working, end-to-end SCA program at small scale.


14. Vulnerability triage: doing it properly

SCA tools produce lots of findings. Triage is the skill that separates people who've used SCA from people who've really used SCA.

14.1 A prioritization model

Don't triage on CVSS alone. Combine signals:

  1. Is it actually present? Confirm identification and version. Check for false positives (CPE mismatch, distro backport, wrong ecosystem).
  2. Is it in shipped/production code? Test-only or build-time-only dependencies are lower risk (though build-time supply-chain attacks are real).
  3. Is it known exploited? On CISA KEV → top priority.
  4. How likely is exploitation? High EPSS → elevate.
  5. Is the vulnerable code reachable? Do you call the affected function? Is the vulnerable feature enabled?
  6. What's the exposure? Internet-facing service vs internal batch job vs CLI tool on a developer laptop.
  7. How severe if exploited? CVSS base score, adjusted for your environment.
  8. Is a fix available, and how disruptive is it? Patch bump vs major version migration.

14.2 Triage outcomes

Every finding should end in one of these states, with a written justification:

  • Fix — upgrade/replace; track to completion with a due date based on severity (SLA, e.g. Critical 7 days, High 30 days).
  • Not affected — the vulnerability doesn't apply (code not present, not reachable, requires configuration you don't use, mitigated by a control). Record a VEX statement.
  • False positive — misidentification. Correct the component data so it doesn't recur.
  • Accept risk (temporary) — documented exception with an owner and an expiry date.
  • In triage — still being investigated (should not live here long).

14.3 Upgrading safely

  • Prefer the minimal safe upgrade of the direct dependency that brings in a fixed transitive version.
  • When the direct dependency hasn't released a fix, use your ecosystem's override mechanism (npm overrides, Yarn resolutions, Maven dependencyManagement, Gradle constraints, Cargo [patch]), test thoroughly, and remove the override later.
  • Automate routine upgrades with Renovate or Dependabot; small, frequent upgrades are far cheaper than giant overdue ones.

15. Common pitfalls and how to avoid them

Pitfall Why it happens Fix
Scanning without lockfiles Manifest ranges, not resolved versions Commit lockfiles; scan after dependency resolution
Scanning source, shipping something else Build adds components (base images, downloaded binaries, vendored tools) Also scan the final artifact/image; generate SBOMs at build time
Alert fatigue Thousands of unprioritized findings Baseline, prioritize via KEV/EPSS/reachability, gate only on new high-confidence issues
Ignoring transitive deps Only direct deps reviewed Use tools that show full graphs and paths
Trusting declared licenses blindly Metadata is often wrong or incomplete Deep license scanning for distributed products
Missing C/C++ and vendored code No package manager metadata Signature/snippet scanning, Conan/vcpkg metadata, manual declarations
Permanent "temporary" exceptions No expiry or owner Exceptions with expiry, scoped to a specific version
One-time scanning Scan at release, never again Continuous monitoring of stored SBOMs
Hard gates on day one Blocking everything breaks the business Report-only → baseline → gradual enforcement
Treating distro packages like upstream Backported fixes ignored Use distro security trackers; prefer tools with distro-aware matching
Including dev/test noise in product reports Scope not configured Separate scopes; report production dependencies for customers
No ownership Findings land on "security" with no team accountable Map projects to owning teams; route findings to their backlog

16. Metrics and reporting

What mature programs measure:

  • Coverage — % of applications/repos/images scanned; % of releases with an SBOM.
  • Mean time to remediate (MTTR) by severity.
  • SLA compliance — % of Critical/High fixed within SLA.
  • Open findings trend — total and by severity, ideally trending down.
  • Exception count and age — how many waivers, how many expired.
  • License policy violations per release.
  • Dependency freshness — how far behind latest your components are ("libyears" is one such metric).
  • Noise ratio — % of findings closed as false positive/not affected (high values mean you need better tooling or tuning).

17. Talking about SCA in an interview

Job postings often list "experience using SCA tools (e.g. FossID, Black Duck, Flexera)." Interviewers generally care that you understand the concepts and workflow; specific tool UIs can be learned in days. Be honest about which tools you've used directly. If your hands-on experience is with open-source tools from the lab above, say so plainly and explain how it maps to the commercial products — that's a credible, concrete answer.

Questions you should be able to answer:

"What is SCA and how is it different from SAST?" SCA identifies third-party components and matches them against known vulnerability and license data; SAST analyzes your own code for unknown bugs.

"How do SCA tools detect components?" Manifest/lockfile parsing, build-time resolution, file hashing, snippet fingerprinting, binary analysis, OS package databases in containers. Explain the trade-offs: dependency-based is fast but blind to copied code; snippet scanning is thorough but review-heavy.

"Why would you use FossID or Black Duck snippet scanning instead of just Dependabot?" Because copied or vendored code, especially in distributed or embedded products, carries license obligations that package-manager-based tools can't see. Also for audits and M&A due diligence.

"How do you handle a critical CVE alert in a transitive dependency?" Confirm identification and version; check KEV/EPSS/reachability/exposure; find the path; upgrade the direct dependency or apply an override; if not affected, document a VEX statement; track to closure.

"How would you roll out SCA gating in CI without breaking teams?" Report-only first, baseline, triage existing debt, then block only new violations of a narrow high-confidence policy, expand over time, provide exception workflows with expiry.

"What's the difference between GPL and LGPL and why does it matter?" GPL copyleft extends to the combined work on distribution; LGPL allows proprietary code to link to the library if users can replace it. Different policy treatment for distributed products. AGPL extends obligations to network use — critical for SaaS.

"What outputs do you produce?" SBOMs (SPDX/CycloneDX), attribution notices, VEX statements, compliance reports, dashboards.

"What are the limitations of SCA?" Only finds known vulnerabilities; depends on data quality; CPE matching causes false positives; NVD enrichment gaps; C/C++ coverage is hard; reachability is approximate; doesn't catch zero-days or malicious code that isn't yet catalogued.


18. Glossary

Term Meaning
AGPL Affero GPL; copyleft triggered by network use
Attribution Required credit/notice for third-party components
BDSA Black Duck Security Advisory
Binary analysis Identifying components in compiled artifacts
Copyleft License requiring derivatives to keep the same license
CPE Common Platform Enumeration product identifier used by NVD
CVE Common Vulnerabilities and Exposures identifier
CVSS Vulnerability severity score (0–10)
Declared license License stated in metadata
Detected license License found in file contents
Concluded license License determined to apply after review
Direct dependency Explicitly declared dependency
EPSS Probability of exploitation in the next 30 days
GHSA GitHub Security Advisory
Identification Human confirmation of what a match actually is
KB Knowledge base of components, fingerprints, licenses, vulns
KEV CISA Known Exploited Vulnerabilities catalog
Lockfile Exact resolved dependency versions
NVD US National Vulnerability Database
OSPO Open Source Program Office
OSV Open Source Vulnerabilities schema and database
Permissive License with minimal obligations
Policy Rules turning findings into allow/warn/block decisions
purl Package URL — standard package identifier
Reachability Whether vulnerable code is actually invoked
SBOM Software Bill of Materials
Snippet Fragment of copied third-party code
Transitive dependency Dependency of a dependency
VEX Vulnerability Exploitability eXchange
Waiver / exception Approved, documented policy deviation

19. Further reading

  • OWASP Dependency-Track — https://dependencytrack.org
  • OWASP Component Analysis project — https://owasp.org/www-community/Component_Analysis
  • OSV.dev — https://osv.dev
  • CISA Known Exploited Vulnerabilities — https://www.cisa.gov/known-exploited-vulnerabilities-catalog
  • FIRST EPSS — https://www.first.org/epss/
  • SPDX License List — https://spdx.org/licenses/
  • Package URL specification — https://github.com/package-url/purl-spec
  • ScanCode Toolkit — https://github.com/aboutcode-org/scancode-toolkit
  • OSS Review Toolkit (ORT) — https://github.com/oss-review-toolkit/ort
  • Trivy — https://trivy.dev
  • Anchore Syft & Grype — https://github.com/anchore
  • OpenChain Project (ISO/IEC 5230 open-source license compliance standard) — https://www.openchainproject.org
  • Vendor documentation: FossID, Black Duck, Revenera Code Insight
  • Companion guide: Software Bill of Materials (SBOM) Formats: SPDX and CycloneDX from Zero