Safeguard
Supply Chain

SCA Code: What Composition Analysis Actually Reads in Your Repo

A concrete look at which files SCA tooling actually parses in a repository, how it builds a dependency tree, and why SCA is required even when your own code is clean.

Safeguard Team
Product
5 min read

Software composition analysis doesn't read your application logic at all, and that surprises people the first time they see a scan finish in seconds against a codebase with hundreds of thousands of lines. SCA code refers to the manifest and lockfiles — package.json, requirements.txt, pom.xml, go.mod, and their lockfile counterparts — that a composition analysis tool parses to build a full dependency tree and check every entry against known vulnerability and license databases. It's inventory and cross-reference, not code review, which is exactly why it's a distinct discipline from SAST rather than a subset of it.

Which files does an SCA scanner actually open?

An SCA scanner starts with manifest files that declare direct dependencies — package.json for npm, requirements.txt or Pipfile for Python, pom.xml or build.gradle for Java, go.mod for Go, Gemfile for Ruby — and then reads the corresponding lockfile (package-lock.json, poetry.lock, go.sum) to resolve the exact, pinned versions of every transitive dependency those direct dependencies pull in. The lockfile matters more than the manifest for accuracy: a manifest might say ^4.17.0, which could resolve to any version in that range depending on when it was installed, while the lockfile records the exact version that actually got resolved and installed at build time. Some scanners also inspect built artifacts directly — a compiled JAR, a Docker image's installed package list — to catch dependencies that never appear in a manifest at all, like packages baked into a base image.

How does the tool turn that file list into a risk assessment?

Once the dependency tree is resolved, each package-and-version pair gets checked against vulnerability databases (the National Vulnerability Database, GitHub Advisory Database, and vendor-specific feeds) to surface known CVEs, and against license databases to flag copyleft or otherwise restrictive terms. The tree structure matters here too — a critical CVE in a transitive dependency four levels deep is still your risk, even though nobody on your team explicitly chose to install that package; it came along because a direct dependency depends on it. Good SCA tooling shows that full path (your app → direct dependency → transitive dependency → vulnerable package) so a developer can actually trace where the fix needs to go, whether that's bumping the direct dependency to a version that pulls a patched transitive version, or overriding the resolution manually.

Why is SCA required even when your own code has zero vulnerabilities?

SCA is required because the overwhelming majority of a typical application's code, by line count, is dependencies you didn't write — open-source packages, transitive dependencies, and vendored libraries — and a SAST scan of your own source code says nothing about vulnerabilities living in that imported code. Log4Shell (CVE-2021-44228) is the reference example: the vulnerability lived entirely inside the log4j-core library, and organizations with immaculate, well-reviewed application code were still exposed if that library sat anywhere in their dependency tree. Regulatory and procurement requirements increasingly make SCA and SBOM generation explicitly required rather than optional — a growing share of enterprise and government software procurement now asks for a dependency inventory as a condition of purchase, independent of how clean the vendor's own code is.

What's the practical output an SCA scan produces?

A useful SCA scan produces three things: a full dependency inventory (often exportable as an SBOM in SPDX or CycloneDX format), a list of known CVEs mapped to specific packages and versions with severity and exploitability context, and a license report flagging anything incompatible with your intended distribution model. The inventory alone has value independent of vulnerabilities — it's what lets a team answer "are we affected by this new CVE" in minutes instead of days when a fresh zero-day drops, because the dependency tree is already indexed rather than needing to be reconstructed under pressure. Safeguard's SCA product generates this inventory continuously so it's current at any point in time, not just at the moment someone last ran a manual scan.

How does SCA fit alongside SAST and DAST rather than replacing them?

SCA, SAST, and DAST test different things and none of them substitutes for the others: SCA inventories and checks third-party dependencies, SAST analyzes your own source code for insecure patterns, and DAST attacks the running application from the outside the way an actual attacker would. A dependency vulnerability caught by SCA, a SQL injection pattern caught by SAST, and a misconfigured authentication endpoint caught by DAST are three unrelated categories of risk that happen to all fall under the "application security testing" umbrella. Running SAST/DAST alongside SCA in the same pipeline, rather than as separate disconnected tools, is what gives a team a full picture instead of three partial ones.

FAQ

Does SCA scan the actual logic inside third-party packages?

No — it identifies the package and version, then checks that identity against known vulnerability databases. It doesn't re-analyze the dependency's source code the way SAST analyzes your own code, which is why a zero-day with no published advisory yet won't show up until the database catches up.

What's the difference between a manifest and a lockfile for SCA purposes?

The manifest declares intended version ranges for direct dependencies; the lockfile records the exact resolved versions, including every transitive dependency. SCA accuracy depends heavily on reading the lockfile, since that's what actually got installed.

Can SCA scan dependencies that aren't in any manifest file at all?

Yes, for dependencies baked into container base images or vendored directly into the repo without a package manager entry — this requires binary or filesystem-level scanning rather than manifest parsing, which is why container image scanning is often bundled alongside SCA rather than treated as a fully separate tool.

Is SCA required for compliance frameworks like SOC 2?

Increasingly yes, in practice — many frameworks and enterprise procurement processes now expect a documented dependency inventory and vulnerability management process as evidence, even where the language isn't tool-specific.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.