Skip to content

sbom: make the CycloneDX serialNumber a valid deterministic urn:uuid - #147

Merged
WintersCoder merged 4 commits into
IkarusAILabs:mainfrom
chiragjangiir:fix/143-cyclonedx-serial-number-uuid
Oct 25, 2026
Merged

WintersCoder merged 4 commits into
IkarusAILabs:mainfrom
chiragjangiir:fix/143-cyclonedx-serial-number-uuid

Conversation

@chiragjangiir

Copy link
Copy Markdown
Contributor

Resolves #143

Summary

CycloneDX requires serialNumber to follow an RFC 4122 UUID URN format matching ^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$. Previously, scripts/gen_sbom.py output urn:uuid:openpulse-lock-<sha256[:32]>, which caused strict validators to reject the archived SBOM.

Changes

  1. Updated scripts/gen_sbom.py to derive serialNumber using uuid.uuid5(uuid.NAMESPACE_URL, f"urn:openpulse:lock:{digest}").
  2. Added unit tests in tests/test_gen_sbom.py asserting:
    • serialNumber adheres strictly to RFC 4122 UUID URN regex.
    • Output remains deterministic across identical runs (supporting CI cmp byte check).
    • Distinct lock contents produce distinct serial numbers.

Verification

  • Ran pytest tests/test_gen_sbom.py -> 2 passed.
  • Ran CI pipeline steps:
    python scripts/gen_sbom.py && python -m json.tool sbom.json > /dev/null
    cp sbom.json /tmp/sbom-first.json && python scripts/gen_sbom.py && cmp sbom.json /tmp/sbom-first.json
    Both succeeded with zero differences.

WintersCoder
WintersCoder previously approved these changes Oct 25, 2026
WintersCoder and others added 3 commits October 25, 2026 16:24
Maintainer follow-up on IkarusAILabs#147 (review findings):

- ruff: 4 errors would fail CI's `ruff check .` (E501 x3, unused
  `Path` import). Fixed by moving the UUID into a `serial_number()`
  helper and rewriting the tests.
- Namespace: the serial was uuid5(NAMESPACE_URL, "urn:openpulse:lock:..")
  - a URN hashed under the URL namespace. It now uses OpenPulse's own
  namespace, uuid5(NAMESPACE_DNS, "openpulse.ikaruslabs.net"), so
  OpenPulse serials stay disjoint from other names under the standard
  namespaces. Still RFC 4122 v5, deterministic per lock.
- main() ignored argv[1], so `gen_sbom.py other.lock out.json` silently
  described requirements.lock; it also built the SBOM twice. It now
  reads [LOCK [OUT]] and builds once. CI calls it without arguments,
  so CI behaviour is unchanged.
- Tests use fixture locks under tmp_path (no dependency on the real lock
  or the cwd), check the namespace, and compare main()'s written bytes
  across runs - the property CI's `cmp` step relies on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@WintersCoder
WintersCoder merged commit 481e6f1 into IkarusAILabs:main Oct 25, 2026
8 checks passed
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.

sbom: make the CycloneDX serialNumber a valid deterministic urn:uuid

3 participants