Software Composition Analysis (SCA): Open Source Dependency Scanning in CI/CD Pipelines

Retool's new app builder is where AI-generated code ships safely
Building apps with AI is easy. Getting them to production safely is another story.
Open source software consumption has grown faster than open source security practice. Applications that import a dozen direct dependencies end up with 500-1,500 total packages in their transitive dependency tree, each independently maintained by different authors with different security practices. The CVEs published against these packages arrive continuously — the Log4Shell disclosure in 2021 affected an estimated 40% of all internet-facing applications. Without automated tooling, there is no practical way to track whether your dependency tree contains known vulnerabilities.
SCA tools solve the discovery problem. The operational challenge is configuring them to produce actionable signal rather than overwhelming noise, and integrating them into the development workflow in a way that developers treat as a helpful tool rather than an obstacle.
SCA implementation: start with visibility, progress to enforcement
The most common SCA implementation failure is enabling blocking gates before developers understand the tool, which produces a wall of failing builds and trains teams to suppress or work around findings. The proven alternative is a staged rollout: report-only mode for 30 days to establish a baseline, followed by Dependabot automated PRs for remediation, and finally blocking gates starting at critical-only severity. This section covers both phases in detail, including how to configure OSV-Scanner and Snyk in report-only mode, how to generate the baseline findings export that becomes the suppression list for the enforcement phase, and how to structure the Dependabot security updates configuration that handles routine CVE remediation without developer intervention.
Phase 1: Enable SCA scanning across all repositories in report-only mode
For GitHub repositories: enable Dependabot security alerts (free, automatic) and configure the GitHub dependency graph. For each application repository: add the OSV-Scanner or Snyk scan step to the CI pipeline in report-only mode (scan runs, findings are printed, build does not fail). Run for 30 days. Export a baseline findings report for all repositories showing the total CVE count, severity distribution, and affected package count. This baseline establishes the pre-enforcement state, identifies the repositories with the highest finding volumes, and gives development teams time to familiarize themselves with the SCA output before it blocks their builds.
Phase 2: Enforce CI gates and configure Dependabot PRs for remediation
After the baseline period: enable Dependabot to automatically open pull requests for security updates (Security > Code Security and Analysis > Dependabot security updates). Configure auto-merge for Dependabot PRs that pass CI tests — this keeps dependencies current with minimal developer involvement. Enable CI blocking for Critical severity findings introduced after the baseline date: configure the SCA tool with a severity threshold (--severity CRITICAL) and --fail-on flag. Communicate the new gate to engineering teams with documentation of how to handle a failing SCA scan (suppression process for non-exploitable findings, remediation path for exploitable ones). Track the critical CVE count as a security metric and report it to engineering leadership monthly.
Selecting and configuring SCA tooling for your environment
The right SCA tool depends on your language ecosystem, hosting environment, and whether you need license compliance scanning alongside vulnerability detection. For teams on GitHub with a single primary language, Dependabot plus OSV-Scanner covers most needs at no cost. For polyglot repositories spanning Go, Python, and JavaScript, OSV-Scanner's unified multi-lockfile scanning reduces the integration overhead of running separate tools per language. For organizations that distribute software commercially and need license compliance enforcement alongside CVE scanning, a commercial tool like Snyk or FOSSA is worth the investment. This section covers the specific configuration for the two most common open-source scenarios to give teams a working starting point.
Multi-language polyglot repositories: OSV-Scanner
For repositories containing multiple languages (Go backend, Python data pipeline, JavaScript frontend): OSV-Scanner provides consistent scanning across all ecosystems in a single tool invocation. Install: curl -fsSL https://github.com/google/osv-scanner/releases/latest/download/osv-scanner_linux_amd64 -o osv-scanner. Run: osv-scanner --lockfile go.sum --lockfile requirements.txt --lockfile package-lock.json --format json -o scan-results.json. The JSON output can be parsed by CI tooling to fail the build on critical findings. OSV-Scanner's data comes from the OSV database, which aggregates CVE data from NVD, GitHub Security Advisories, and package-specific advisory databases, providing broader coverage than single-source scanners.
License compliance for commercial software distribution
If your organization distributes software commercially: add license scanning to the SCA pipeline using FOSSA (commercial) or the OSS Review Toolkit (ORT, open source). Configure a license allowlist (MIT, Apache 2.0, BSD-2-Clause, BSD-3-Clause, ISC are typically allowed) and blocklist (GPL-2.0, GPL-3.0, AGPL-3.0 require legal review before use). The CI pipeline should fail on any newly introduced package with a blocked license. Existing packages with blocked licenses that are already in production should be reviewed by legal counsel for compatibility with your distribution model. Many GPL license issues in commercial products trace back to an SCA scan that was never run rather than an intentional decision to accept GPL terms.
Briefings like this, every morning before 9am.
Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.
The bottom line
SCA implementation has a clear path that avoids the two most common failure modes: overwhelming developers with thousands of findings from day one (causes SCA to be treated as noise), or failing to enforce any gate (makes SCA purely informational with no security impact). The correct path: enable scanning in report-only mode, generate a baseline, configure Dependabot for automated fix PRs, then enable blocking gates starting with critical-only and expanding to high after the critical backlog is cleared. Combine with SBOM generation for each release to enable rapid triage when new CVEs are disclosed. The metric that matters: the time between a critical CVE's public disclosure and its remediation across all affected applications in your organization — SCA with enforced CI gates and Dependabot automation should compress this from weeks (manual discovery) to days (automated PR and merge).
Frequently asked questions
What is the difference between SCA, SAST, and DAST, and which do I need?
These are three complementary, non-overlapping security testing approaches: SCA (Software Composition Analysis): scans open source and third-party dependencies for known CVEs. Finds vulnerabilities you did not write. SAST (Static Application Security Testing): analyzes your own source code for security vulnerabilities (SQL injection, XSS, insecure cryptography) without running the application. Finds vulnerabilities you wrote. DAST (Dynamic Application Security Testing): tests a running application by sending attack payloads and observing responses. Finds vulnerabilities exploitable at runtime, including configuration issues and runtime behavior. All three are needed for a comprehensive application security program, but the implementation priority differs: SCA is the fastest to implement and addresses a large immediate attack surface (known CVEs in widely-used libraries). SAST requires language-specific tools and produces a learning curve for developers. DAST requires a running test environment. Most teams implement SCA first, then SAST, then DAST as their program matures.
Which SCA tool should I use: Snyk, OWASP Dependency-Check, Dependabot, or OSV-Scanner?
Tool selection by use case: Dependabot (GitHub native, free): best for GitHub-hosted repositories, automatic PR creation for dependency upgrades, broad language support (Python, JavaScript, Ruby, Go, Java, Rust, PHP). No CI gate feature — it opens PRs but does not block merges. Integrate with Dependabot security alerts for alerting on unpatched CVEs. OWASP Dependency-Check (open source, free): battle-tested Java-centric scanner, also supports Python, JavaScript, .NET. Can be integrated into any CI system. Less accurate than commercial tools on some ecosystems. Good for regulated environments that cannot use commercial cloud-connected tools. OSV-Scanner (Google, open source, free): newer, very fast, excellent multi-language support, queries the OSV vulnerability database which aggregates NVD + GitHub Advisory + package-specific advisories. Best for polyglot repositories. Snyk (commercial, free tier available): most developer-friendly UX, actionable remediation guidance, IDE plugins, best-in-class accuracy, license compliance scanning included. The free tier covers most small-team needs. For large organizations: Snyk or a similar commercial tool provides the best developer experience and broadest database coverage.
How do I integrate SCA into my CI/CD pipeline without creating developer friction?
CI/CD integration strategy that minimizes friction: (1) Start with report-only mode: run the SCA scan but do not fail the build on findings for the first 30 days. This establishes a baseline of existing findings without immediately blocking deployments. (2) Establish a findings baseline: all vulnerabilities found in report-only mode are 'accepted risk' (they existed before the gate was enforced). Add them to a suppression list or set the gate to only fail on findings introduced after the baseline date. (3) Enable blocking for new critical CVEs only: configure the gate to fail builds only if a newly introduced dependency has a critical CVE (CVSS 9.0+). This catches the highest-risk new dependencies without blocking for existing backlog. (4) Expand severity thresholds over time: after developers are familiar with the tool and the critical backlog is addressed, expand blocking to High severity (CVSS 7.0-8.9). (5) Provide remediation suggestions in the CI output: the best SCA tools output the vulnerable package name, CVE, affected version range, and the fixed version — developers can fix the issue without leaving the CI output.
How should I triage SCA findings to focus on what actually matters?
SCA finding triage framework: (1) Severity: critical (CVSS 9.0+) — investigate immediately, block deployment. High (7.0-8.9) — remediate in next sprint. Medium and below — track in backlog, remediate when dependency is updated for other reasons. (2) Exploitability: is the vulnerable code path actually called by your application? A path traversal CVE in a library function that your code never calls is not exploitable. Some commercial SCA tools (Snyk, Endor Labs, Semgrep Supply Chain) perform reachability analysis to distinguish exploitable from non-exploitable findings. (3) Availability of a fix: a CVE with no fix available requires a risk acceptance decision; a CVE with a fixed version available requires remediation planning. (4) Application exposure: a CVE in a dependency used only in a CLI tool for internal developer use has lower risk than the same CVE in a dependency used in your customer-facing API. Prioritize findings in externally-exposed services over internal tools.
What is license compliance scanning and why does it matter for my organization?
License compliance scanning identifies open source packages in your dependency tree and flags licenses that may create legal obligations for your organization. Common license categories: Permissive licenses (MIT, Apache 2.0, BSD): generally safe for commercial use, require attribution in some cases, do not require sharing source code. Copyleft licenses (GPL v2/v3, LGPL): require that any software distributed that links to or includes GPL code must also be distributed under GPL — this is often incompatible with proprietary commercial software distribution. Weak copyleft (LGPL, MPL): less restrictive copyleft that allows linking from proprietary code under specific conditions. License scanning tools (Snyk, FOSSA, WhiteSource) generate a software license inventory and flag packages with licenses that violate your organization's policy. This is particularly important if your organization distributes software commercially or contributes to open source — using a GPL library in a commercial product without legal review can create significant legal exposure.
What is an SBOM and how do I generate one with SCA tools?
A Software Bill of Materials (SBOM) is a machine-readable inventory of all software components in an application — all direct and transitive dependencies, their versions, and their associated licenses and known vulnerabilities. Two common SBOM formats: CycloneDX (OWASP project, broadly supported) and SPDX (Linux Foundation, ISO standard). Generate with SCA tools: OWASP Dependency-Check: run with --format ALL to output CycloneDX XML. Syft (open source): syft your-image:latest -o cyclonedx-xml > sbom.xml. Snyk: snyk sbom --format=cyclonedx1.4+json > sbom.json. CycloneDX CLI tools: can generate SBOM from package manifests (package.json, requirements.txt, go.mod). Use case for SBOMs: when a new critical CVE is disclosed (like Log4Shell), query your SBOM inventory to immediately determine which applications contain the affected component, enabling rapid triage without waiting for a scanner to run against all repositories.
How do I handle transitive dependency vulnerabilities that I cannot directly fix?
Transitive dependency CVEs (vulnerabilities in packages you depend on indirectly through another package) cannot always be fixed by updating your direct dependencies. Options when a transitive CVE cannot be resolved by dependency updates: (1) Check if the direct dependency that introduces the transitive dependency has a newer version that uses a fixed version of the transitive package — often the direct dependency's maintainers have already updated their dependencies in a new release. (2) Override the transitive dependency: most package managers allow forcing a specific version of a transitive dependency regardless of what the direct dependency specifies (npm overrides, pip's constraints.txt, Maven dependency management). Use this to pin the transitive dependency to a fixed version, with a comment documenting why. (3) Submit an issue or PR to the direct dependency's maintainer requesting they update to the fixed transitive version. (4) Replace the direct dependency with an alternative that does not introduce the vulnerable transitive dependency. (5) Accept the risk with documentation if the vulnerable code path is not reachable from your application — document the risk acceptance with a suppression comment and a review date.
Sources & references
Free resources
Critical CVE Reference Card 2025–2026
25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.
Ransomware Incident Response Playbook
Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.
Get threat intel before your inbox does.
50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.
Unsubscribe anytime. We never sell your data.

Founder & Cybersecurity Evangelist, Decryption Digest
Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.
Win a $2,495 Black Hat pass.
Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.
