Skip to main content

SBOM Generation Review

Current State

SBOM Tool Used

  • Tool: anchore/sbom-action v0.20.9
  • Underlying Engine: Syft (by Anchore)
  • Version Hash: 8e94d75ddd33f69f691467e42275782e4bfefe84

Format

  • Primary Format: CycloneDX JSON (cyclonedx-json)
  • File Name: sbom.cdx.json
  • Standard Compliance: CycloneDX specification (industry-standard SBOM format)

Generation Trigger

SBOM generation occurs in two workflows:

  1. Tag Assets Workflow (.github/workflows/tag-assets.yml)

    • Triggered on: Git tags matching v*.*.* pattern
    • Triggered on: Manual workflow dispatch
    • Purpose: Generate SBOM for tagged releases
  2. Release Workflow (.github/workflows/release.yml)

    • Triggered on: Manual workflow dispatch only
    • Purpose: Generate SBOM during npm package publication

Files Generated

  • sbom.cdx.json - CycloneDX JSON format SBOM
  • Uploaded as GitHub Actions artifact with name: sbom.cdx.json

Attachment to Release

CRITICAL ISSUE IDENTIFIED: The SBOM is generated and uploaded as a GitHub Actions artifact, but it is NOT automatically attached to the GitHub Release.

Current Behavior:

  1. SBOM is generated by anchore/sbom-action
  2. SBOM is uploaded as workflow artifact (accessible from workflow run page)
  3. GitHub Release is created by softprops/action-gh-release
  4. Gap: No step to attach the SBOM artifact to the release

What's Working

  1. Standardized SBOM Generation

    • Uses industry-standard CycloneDX JSON format
    • Leverages reputable Anchore/Syft tooling
    • Pinned to specific version hash for reproducibility
  2. Comprehensive Dependency Scanning

    • Scans entire project directory (.)
    • Captures all dependencies from pnpm-lock.yaml
    • Includes transitive dependencies
  3. Dual Workflow Coverage

    • SBOM generated for both tagged releases and npm publications
    • Ensures SBOM availability across different release mechanisms
  4. Security Documentation

    • Excellent documentation in docs/security-supply-chain.md
    • Clear verification procedures documented
    • Integration with broader security strategy (OSV scanning, Harden-Runner)
  5. Build Environment

    • SBOM generated after successful build step
    • Ensures accuracy of dependency resolution
    • Uses frozen lockfile for deterministic builds

Issues Found

Critical (P0)

  1. SBOM Not Attached to GitHub Releases
    • Problem: SBOM artifact exists but isn't included in release assets
    • Impact: Users cannot access SBOM from release page; must dig into workflow run artifacts
    • Evidence: No files: parameter in softprops/action-gh-release step
    • Expected Behavior: SBOM should be downloadable from Releases page alongside other assets

High (P1)

  1. Missing Vulnerability Scanning of SBOM

    • Problem: SBOM is generated but not scanned for vulnerabilities in tag-assets workflow
    • Impact: Releases may include known vulnerabilities without immediate detection
    • Note: Separate OSV scanning exists in security.yml but runs on schedule, not on release
  2. No SBOM Validation Step

    • Problem: No verification that generated SBOM is valid CycloneDX
    • Impact: Malformed SBOM could be published without detection
    • Recommendation: Add validation step using CycloneDX CLI or similar

Medium (P2)

  1. Single Format Only

    • Problem: Only CycloneDX JSON format is generated
    • Impact: Organizations requiring SPDX format cannot consume SBOM
    • Note: Documentation mentions this as acceptable; SPDX addition if "downstream tooling demands"
  2. No SBOM Signing/Attestation

    • Problem: SBOM is not cryptographically signed
    • Impact: No way to verify SBOM integrity or authenticity
    • Note: NPM provenance exists for package, but not SBOM-specific attestation

Low (P3)

  1. Artifact Retention Not Explicitly Set
    • Problem: Workflow artifacts may expire based on default retention
    • Impact: SBOM artifacts could be lost after retention period
    • Note: Less critical if attached to release (permanent storage)

Recommendations

Immediate Actions (P0)

  1. Attach SBOM to GitHub Releases
    - name: Create GitHub Release
    uses: softprops/action-gh-release@v2.4.2
    with:
    generate_release_notes: true
    files: |
    sbom.cdx.json
    env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Short-Term Actions (P1)

  1. Add SBOM Vulnerability Scanning

    • Add Grype or Trivy scan step after SBOM generation
    • Gate release if critical vulnerabilities detected
    • Example using Grype:
    - name: Scan SBOM for Vulnerabilities
    uses: anchore/scan-action@v3
    with:
    sbom: sbom.cdx.json
    fail-build: true
    severity-cutoff: high
  2. Add SBOM Validation

    - name: Validate SBOM
    run: |
    npm install -g @cyclonedx/cyclonedx-cli
    cyclonedx validate --input-file sbom.cdx.json --fail-on-errors

Medium-Term Actions (P2)

  1. Consider Multi-Format SBOM Generation

    • Evaluate if any consumers require SPDX format
    • If yes, generate both CycloneDX and SPDX formats
    • Use separate artifact names: sbom.cdx.json and sbom.spdx.json
  2. Implement SBOM Signing

    • Use Cosign for keyless signing
    • Generate attestation using GitHub OIDC
    • Example (for container images):
    # Add at job level
    permissions:
    id-token: write # Required for OIDC token
    attestations: write # Required for attestation creation

    steps:
    - name: Install Cosign
    uses: sigstore/cosign-installer@v3

    - name: Create SBOM Attestation
    run: |
    # For container images: replace with your image and digest
    cosign attest --type cyclonedx \
    --predicate sbom.cdx.json \
    ${{ env.IMAGE_NAME }}@sha256:${{ env.IMAGE_DIGEST }}

    Note: For npm packages (non-container), consider using npm provenance (--provenance flag) or the GitHub Attestations API instead of Cosign, as Cosign is primarily designed for container images.

Long-Term Actions (P3)

  1. Set Explicit Artifact Retention

    - name: Generate SBOM
    uses: anchore/sbom-action@8e94d75ddd33f69f691467e42275782e4bfefe84
    with:
    path: .
    format: cyclonedx-json
    artifact-name: sbom.cdx.json
    retention-days: 90
  2. Add VEX Support

    • Implement CycloneDX VEX extension
    • Document known vulnerabilities with exploitability context
    • Reduces false positive noise in vulnerability scanners

Best Practices Compliance

  • SBOM generated for every release
  • Uses standard format (CycloneDX)
  • Attached to GitHub releases (CRITICAL GAP)
  • Includes all dependencies
  • Machine-readable format
  • Vulnerability scanning performed at release time (scheduled only)
  • SBOM is signed/attested

Compliance Score: 4/7 (57%)


Security Integration Analysis

Current Security Stack

The project has a robust security posture with:

  1. NPM Provenance - Sigstore-backed attestation for published packages
  2. Dependency Review - Gates PRs with vulnerable dependencies (moderate+ severity)
  3. OSV Scheduled Scanning - Weekly vulnerability detection
  4. Harden-Runner - Egress monitoring in audit mode
  5. SBOM Generation - CycloneDX inventory (this review's focus)

Integration Gaps

  1. SBOM and OSV Scanning Are Disconnected

    • OSV runs weekly on schedule
    • SBOM generated on release
    • No immediate vulnerability check when releasing
  2. SBOM Accessibility

    • Documented as "download from workflow artifacts"
    • Should be first-class release asset for transparency
  3. Provenance vs SBOM Attestation

    • NPM package has provenance
    • SBOM itself has no attestation
    • Both should be verifiable

Next Steps

Phase 1: Fix Critical Gap (Week 1)

  1. Update tag-assets.yml to attach SBOM to release
  2. Test with pre-release tag (e.g., v0.0.0-sbom-test)
  3. Verify SBOM appears in release assets
  4. Update release.yml with same change for consistency

Phase 2: Add Quality Gates (Week 2-3)

  1. Add SBOM validation step
  2. Implement vulnerability scanning of SBOM at release time
  3. Document new quality gates in security-supply-chain.md

Phase 3: Enhanced Security (Week 4+)

  1. Evaluate SBOM signing with Cosign
  2. Consider SPDX format if needed
  3. Explore VEX integration for vulnerability context

Verification Steps

After Phase 1 implementation:

  1. Create test tag: git tag v0.0.1-sbom-fix && git push --tags
  2. Monitor workflow run
  3. Navigate to Releases page
  4. Confirm sbom.cdx.json appears in release assets
  5. Download and validate with: cyclonedx validate --input-file sbom.cdx.json --fail-on-errors

Comparison with Industry Standards

CISA Minimum Elements for SBOM (2021)

  • Supplier Name
  • Component Name
  • Version of Component
  • Other Unique Identifiers
  • Dependency Relationship
  • SBOM Author
  • Timestamp

All minimum elements present in CycloneDX format.

NTIA Framing Document Compliance

  • Automation support (machine-readable JSON)
  • Standardized format (CycloneDX)
  • Practices and processes documented
  • Access and delivery (partially - not on release page)
  • Unique identification (package URIs)

Cost-Benefit Analysis

Current State Costs

  • Developer Time: Minimal (automated)
  • CI Minutes: ~30 seconds per release
  • Storage: ~50KB per SBOM artifact

Gap Remediation Costs

  • Phase 1 (Attach to Release): 1-2 hours (one-time)
  • Phase 2 (Validation + Scanning): 4-6 hours (one-time)
  • Phase 3 (Signing): 8-10 hours (one-time)

Benefits

  • Transparency: Users can audit dependencies
  • Security: Faster vulnerability remediation with accurate inventory
  • Compliance: Meets government/enterprise SBOM requirements
  • Trust: Demonstrates supply chain maturity

Conclusion

The project has a strong foundation for SBOM generation using industry-standard tools and formats. However, there is a critical gap preventing the SBOM from being useful to end users: it's not attached to GitHub releases.

Summary

  • Status: SBOM generation is configured correctly but incomplete
  • Priority: HIGH - Fix attachment to releases immediately
  • Effort: LOW - Simple workflow modification
  • Impact: HIGH - Enables SBOM consumption by users and tooling

Recommendation

Proceed with Phase 1 immediately. The fix is simple, low-risk, and high-value. Once releases include SBOM assets, the project will meet industry best practices for software transparency.