Skip to content

feat(cyclonedx): emit component.scope for dev and prod dependencies - #1488

Merged
sonukapoor merged 2 commits into
OWASP:mainfrom
Nachiket-Roy:cyclonedx-component-scope
Nov 5, 2026
Merged

sonukapoor merged 2 commits into
OWASP:mainfrom
Nachiket-Roy:cyclonedx-component-scope

Conversation

@Nachiket-Roy

@Nachiket-Roy Nachiket-Roy commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

What changed and why

  • The lockfile parsers already identify whether a package is a development or production dependency (PackageRef.dev), but the CycloneDX generator was dropping this information entirely when emitting components. Downstream tools ingesting the SBOM (e.g., Dependency-Track, vulnerability scanners) had no way to filter or prioritize dev-only versus production vulnerabilities.
  • Component scope attribute: Added scope to CycloneDxComponent and updated buildCycloneDxBom to emit:
    • "optional" for development dependencies (pkg.dev === true), per CycloneDX spec guidance for dev/test dependencies.
    • "required" for runtime/production dependencies (pkg.dev === false).
    • Omitted when pkg.dev === undefined (undetermined / no assertion made).
  • Test validation: Added tests in tests/cyclonedx.test.ts covering scope mapping (optional, required, omitted), schema conformance against allowed 1.6 enum values, and end-to-end report serialization via writeCycloneDxReport

Part of #1486

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Summary

Summary by CodeRabbit

  • New Features
    • CycloneDX reports now show development packages with an excluded scope and production packages with a required scope when development status is known. Packages without that information continue to appear without a scope. Scope values are included in serialized reports.
  • Documentation
    • The CycloneDX documentation now describes the scope values for production and development packages, and notes that scope is omitted when development status is unknown.

CycloneDX SBOM components now include scope when package development status is known. Development packages receive "excluded" scope, production packages receive "required" scope, and packages with unknown status omit the field.

Changes: CycloneDX scope mapping

Layer / File(s) Summary
Component scope mapping and validation
src/output/cyclonedx.ts, tests/cyclonedx.test.ts, website/docs/cyclonedx.md
The BOM builder maps package development status to component scope. Tests cover defined and undefined status and serialized reports. The documentation describes the production and development scope values.

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Feature

Merge Risk: Low · up to 3af64

CycloneDX output correctly maps explicit development status, but production Yarn dependencies still omit scope. This bounded metadata gap warrants owner awareness or follow-up; it does not block report generation.

Pre-merge checks: Passed 6 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Linked Issue Warning The pull request body references Part of #1486, but it does not contain Closes, Fixes, Resolves, or Refs followed by an issue number. Update the pull request body to include an accepted reference, such as Refs #1486.
Passed Passed checks: 6 passed
Check name Status Explanation
Title check Passed The title follows the required "type: short description" form with the feat prefix, lowercase after the colon, and no trailing period. It names the change accurately: CycloneDX components gain a scope…
Description check Passed The description covers the required section, "What changed and why", and explains the motivation, which is that dev and prod information was dropped from CycloneDX output. It lists the scope mapping (…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Closes Keyword Matches Scope Passed The pull request body says “Part of #1486” and does not use “Closes,” “Fixes,” or “Resolves.” The issue will not auto-close from this pull request. The reviewed diff also contains no closing keyword.
No New Runtime Dependency Passed The pull request changes only CycloneDX source, tests, and documentation. No package.json file changed, so it adds no entry under dependencies or optionalDependencies and moves no package from devDepe…
Full details: Title check

Explanation

The title follows the required "type: short description" form with the feat prefix, lowercase after the colon, and no trailing period. It names the change accurately: CycloneDX components gain a scope value for dev and prod dependencies. One mismatch remains. The title puts the scope name in the code path and omits the "optional" and "required" values, but this is a minor point and does not make the title misleading.

Full details: Description check

Explanation

The description covers the required section, "What changed and why", and explains the motivation, which is that dev and prod information was dropped from CycloneDX output. It lists the scope mapping (optional, required, omitted when undefined) and the tests added. It links the work to the issue with "Part of #1486". The template uses "Closes #", which the author did not fill in. The leftover HTML comment placeholder "Brief description of the change" also remains in the text. Neither gap blocks the check.

Full details: No New Runtime Dependency

Explanation

The pull request changes only CycloneDX source, tests, and documentation. No package.json file changed, so it adds no entry under dependencies or optionalDependencies and moves no package from devDependencies.

Tip

🎯 Customize your risk assessments

Guide how CodeRabbit assesses merge risk and security architecture risk. Highlight sensitive changes and explain your security boundaries using Merge Risk Instructions and Security Risk Instructions in your review settings. Security architecture risk assessments require the Advanced plan or above.

✅ Automatic approvals, with your rules

Let CodeRabbit approve pull requests once required threads are resolved, pre-merge checks pass, and your risk limits are met. Enable Automatic approvals in review settings, with overrides for teams or file paths.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Automatic approval policy

Commit: 3af6400769d5.

Setting Effective value Source
Automatic approvals Enabled Global configuration
Merge risk Moderate Global configuration
Security risk Not set Global configuration

No overrides matched. The global limits apply.

Not set means no limit was configured after inheritance. Use @coderabbitai configuration to inspect the resolved settings and their sources.

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 1780570 and 3af6400.

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 0 remain after this review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional comments: 1
src/output/cyclonedx.ts-98-98: 1

98-98: Major · Data Integrity & Integration · Heavy lift

Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Do not infer runtime scope from dev alone.

A package in devDependencies can still run in production, such as a CLI used to start the server. This emits optional for that package, but CycloneDX defines optional as unavailable to be called at runtime. Consumers may therefore deprioritize a runtime vulnerability. (raw.githubusercontent.com)

I recommend recording development status in a separate property and setting scope only when runtime availability is known.


Review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 280f098 and 500a9fd.

Files selected for processing: 2
  • src/output/cyclonedx.ts
  • tests/cyclonedx.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 2 remain after this review.

@sonukapoor sonukapoor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Nachiket-Roy. The classification matches #1487 exactly, mixed dev-and-prod packages come out required, Yarn's unflagged packages are left without a scope rather than guessed, and every BOM I generated validates against the CycloneDX 1.6 schema.

The one thing I'd change is the value. 1.6 defines optional as not installed or not callable at runtime, and CycloneDX's own npm tool uses it for optionalDependencies. Dev-only packages match excluded, which the spec describes as usage for test and other non-runtime purposes, not reachable at runtime. Could we emit excluded for dev-only components instead?

Two smaller ones: could you add a scope row to the field table in website/docs/cyclonedx.md, and change Closes #1486 to Part of #1486? The issue covers both formats, so whichever of this and #1487 lands second can close it.

Comment thread tests/cyclonedx.test.ts Resolved
Comment thread src/output/cyclonedx.ts Resolved
Comment thread website/docs/cyclonedx.md Resolved
…output

- Emit 'excluded' instead of 'optional' for dev-only components per CycloneDX 1.6 spec
- Drop vacuous schema enum test in cyclonedx test suite
- Document components[].scope and omit behavior in website field table
@cve-lite-cli-bot

Copy link
Copy Markdown

CVE Lite CLI

No new vulnerabilities introduced by this PR

4 existing findings on the base branch are unchanged by this PR.

Posted because this PR changes dependencies. Nothing is posted when they are untouched.

Scanned by CVE Lite CLI, a free and open source OWASP project.

@sonukapoor sonukapoor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Nachiket-Roy, all three are in: dev-only components are excluded, the docs table has the scope row, and it's Part of #1486. Switching the value back to optional fails the new tests, and the full suite passes on the merge with current main. Approved.

@sonukapoor
sonukapoor merged commit 7b8bb6b into OWASP:main Nov 5, 2026
11 checks passed
@sonukapoor

Copy link
Copy Markdown
Collaborator

Merged - thank you @Nachiket-Roy!

@Nachiket-Roy
Nachiket-Roy deleted the cyclonedx-component-scope branch November 5, 2026 14:31
@sonukapoor sonukapoor mentioned this pull request Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants