|
| 1 | ++++ |
| 2 | +author = "Jason Smith" |
| 3 | +title = "Implementing Data-Aware Signing" |
| 4 | +date = "2026-02-12" |
| 5 | +linkedin = "https://www.linkedin.com/posts/j28smith_sbom-openssf-supplychainsecurity-activity-7424218592931405825-MBC5" |
| 6 | +image = "img/thirdparty/2026-02-02-data-aware-sbom-signing.png" |
| 7 | ++++ |
| 8 | + |
| 9 | +I recently argued that with SBOMs we need to stop signing the "container" (the file) and start signing the "content" |
| 10 | +(the data). But how do we actually implement this without making verification a nightmare? |
| 11 | + |
| 12 | +The answer lies in moving away from simple bit-for-bit hashing and toward Data-Aware Integrity. Here is the technical |
| 13 | +breakdown of how we build a resilient chain of trust. |
| 14 | + |
| 15 | +## 1. The Foundation: JCS |
| 16 | + |
| 17 | +To sign data-aware JSON, you must first transform it into an "invariant format". |
| 18 | +[RFC 8785: JSON Canonicalization Scheme (JCS)](https://www.rfc-editor.org/rfc/rfc8785) is the industry standard for |
| 19 | +this. It ensures that no matter how a tool handles the file, the cryptographic input remains identical. The first |
| 20 | +sentence of the RFC 8785 abstract says it all: |
| 21 | + |
| 22 | +> Cryptographic operations like hashing and signing need the data to be expressed in an invariant format so that the |
| 23 | +> operations are reliably repeatable. |
| 24 | +
|
| 25 | +The JCS process involves: |
| 26 | + |
| 27 | +- **Deterministic Property Sorting:** Keys are sorted lexicographically (alphabetical or dictionary order). |
| 28 | +- **Whitespace Removal:** All unnecessary spaces, tabs, and newlines are stripped. |
| 29 | +- **Numeric Normalization:** Numbers are formatted consistently (1.0 vs 1). |
| 30 | +- **Encoding:** The result MUST be encoded in UTF-8. |
| 31 | + |
| 32 | +By running JCS before you hash, a minified SBOM and a pretty-printed SBOM result in the exact same signature. |
| 33 | + |
| 34 | +## 2. Digital Signatures and the Role of JSF |
| 35 | + |
| 36 | +CycloneDX natively supports **JSON Signature Format (JSF)** for document integrity, whereas the SPDX specification does |
| 37 | +not explicitly define a standard for handling signatures. While SPDX typically relies on external, detached signature |
| 38 | +files, CycloneDX allows for an **embedded signature** directly within the JSON structure. |
| 39 | + |
| 40 | +A critical, albeit specialized, feature of JSF is **Property Exclusion**. This allows producers to cryptographically |
| 41 | +lock the core components of an SBOM while leaving specific fields (such as vulnerabilities and VEX information) |
| 42 | +unsigned. This enables security teams to enrich the SBOM with updated vulnerability context later in the lifecycle |
| 43 | +without invalidating the original build-time signature. |
| 44 | + |
| 45 | +How it works technically: |
| 46 | + |
| 47 | +1. The producer defines a list of fields to be excluded from the signature. |
| 48 | +2. During signing/verification, the tool removes these fields from the SBOM data. |
| 49 | +3. The remaining data to be signed/verified is then passed through the JCS process to create the canonical hash. |
| 50 | +4. The canonical hash is used to generate or verify the SBOM signature. |
| 51 | + |
| 52 | +This ensures that the "facts" provided by the build system are cryptographically locked, even if the "context" around |
| 53 | +them is enriched later in the lifecycle. |
| 54 | + |
| 55 | +## 3. The "Embedded" Challenge |
| 56 | + |
| 57 | +Because CycloneDX signatures can live inside the SBOM document itself, you have a recursive problem: you cannot sign or |
| 58 | +verify a file directly that contains the signature itself. At a basic level, property exclusion is a functional |
| 59 | +necessity and is implied for any embedded signature as the signature property itself must be excluded from the signing |
| 60 | +and verification process to avoid a circular dependency during hashing. |
| 61 | + |
| 62 | +This is why Data-Aware tools are a requirement as simple binary verifiers are structurally blind to the data model. |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +## Building the Standard |
| 67 | + |
| 68 | +I am currently leading an initiative within the [OpenSSF](https://openssf.org/) SBOM Everywhere SIG to codify these |
| 69 | +foundations into an SBOM Signing/Verification Best Practices Guide. We are moving past theory and into implementation. |
| 70 | +We are building the reference implementations with "known-good" test vectors so the industry doesn't have to guess and |
| 71 | +to ensure your tools are truly spec-compliant. |
| 72 | + |
| 73 | +Want to see where we are? We currently have reference implementations completed in Go, Python, and Java, with |
| 74 | +JavaScript and Rust coming soon (and other languages upon request). |
| 75 | + |
| 76 | +💬👇 Comment "SBOM Signing Best Practices" below if you want a link to the current Work-in-Progress and the reference |
| 77 | +code. Happy to get your feedback and input on this work while we are actively working on it. |
0 commit comments