Safeguard
Developer Tools•

How do you spot a dev dependency that reached runtime in an SBOM diff?

Watch the scope field between releases. A component moving from excluded or optional to required means test or build tooling is now part of what you ship.

Safeguard Security Team
3 min read

Compare the scope field of each component between two SBOMs. A component that moves from excluded or optional to required means something once confined to tests or builds is now part of what runs in production. That deserves review, because runtime components carry the real exposure.

What scope means

In CycloneDX, a component's scope says whether it is needed at runtime. Required means the component is needed for runtime, and it is the assumed default when scope is missing. Optional means it may be absent at runtime. Excluded is used for test or other non runtime purposes, and the specification says excluded components are not reachable within a call graph at runtime.

Because missing scope is read as required, generators that omit the field make everything look like runtime. Know what your generator emits before relying on this check.

Why scope changes matter

Teams often set severity and gating rules by scope: block on runtime, warn on development. GitHub's dependency review action works this way, checking runtime scope by default and allowing development and unknown scopes to be added. A component that changes scope silently moves between rule sets.

Typical reasons a component changes scope

ChangeProbable cause
Excluded to requiredA dev tool now imported by application code, or a packaging change
Required to excludedA component correctly moved out of the shipped artifact
Missing to requiredGenerator update that now emits scope
Optional to requiredA plugin or extra became mandatory

Steps

  1. Diff by package URL and include the scope field in the comparison.
  2. Filter to components whose scope moved toward required.
  3. For each, find the import or the packaging change that caused it.
  4. Decide whether it should ship. If not, fix the packaging.
  5. If it should, apply runtime rules to it from now on.

Common ways it happens

A test helper gets imported from production code. A build plugin is added to the main dependency list instead of the development list. A container image copies the whole source tree, including a tools directory, and a scan picks it up. Each is a packaging mistake that grows attack surface without anyone deciding to.

Reachability as a second opinion

Scope is a declaration. Reachability analysis checks whether vulnerable code is actually called. Use both. A required component whose vulnerable function is never reached is lower urgency than one whose function is on a live path, while a scope change tells you where to look first.

Safeguard scans dependencies and SBOMs, applies reachability analysis, and lets policies treat scopes differently. Try a project on the free scan.

Try it yourself

Click through it at your own pace, or open it full screen.

Compare which findings stay once reachability is applied.

Quick check

What does a missing scope mean in CycloneDX?

Consumers should assume required, so a generator that omits scope makes everything look like runtime.

Should development scope components be ignored?

No. Warn on them, since they can reach build systems and developer machines, but block less often.

Sources

Last reviewed: 19 October 2026.

Never miss an update

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

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.