
A CBOM example is the quickest way to understand what a cryptography bill of materials actually records. This post gives three worked examples in CycloneDX 1.7 JSON: a TLS 1.3 endpoint that uses hybrid post-quantum key exchange, an application that uses algorithms through a cryptographic library, and a signing key held in a hardware security module (HSM). Every field is explained in plain English, along with what it tells you about quantum exposure.
Each example is a complete CycloneDX document, and each has been validated against the official CycloneDX 1.7 JSON schema (release 1.7.2). The examples are illustrative: the hosts, keys and serial numbers are invented, and they are not the output of any product. For what a CBOM is and why it matters, see what is a cryptography bill of materials. For how CBOM became part of CycloneDX, see CBOM and CycloneDX.
The building blocks
Five parts of the CycloneDX format carry almost all of a CBOM:
- Components of type
cryptographic-asset. Every algorithm, certificate, protocol and key is a component, alongside the applications, libraries and devices an ordinary SBOM already lists. cryptoProperties.assetType. The schema allows four values:algorithm,certificate,protocolandrelated-crypto-material(keys, tokens, secrets and similar). Each value unlocks its own block of properties.bom-ref. A unique identifier for each component inside the document. Every relationship in a CBOM is expressed by pointing at abom-ref.- Dependencies.
dependsOnsays one component uses another.provides, added in CycloneDX 1.6, says a component implements something. The CycloneDX guide is precise about the difference: “A component that implements another component does not imply that the implementation is in use.” - Security levels.
classicalSecurityLevelrecords classical strength in bits.nistQuantumSecurityLevelrecords the NIST post-quantum security category, where categories 1, 3 and 5 are defined by comparison with key search on AES-128, AES-192 and AES-256. The schema states: “A value of 0 indicates that none of the categories are met.”
CycloneDX 1.7, released on 21 October 2025, added a standardised list of algorithm families and a list of elliptic curves. The algorithmFamily and ellipticCurve fields must use values from those lists, and the older free-text curve field is deprecated. The examples below use the registry values throughout.
Example 1: a TLS 1.3 endpoint with hybrid key exchange
A public web server negotiates TLS 1.3 with the cipher suite TLS_AES_256_GCM_SHA384 and the hybrid key exchange group X25519MLKEM768. Its certificate carries an RSA-2048 key.
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"version": 1,
"components": [
{
"type": "cryptographic-asset",
"bom-ref": "protocol/tls13-www-example-com-443",
"name": "TLS 1.3 on www.example.com:443",
"cryptoProperties": {
"assetType": "protocol",
"protocolProperties": {
"type": "tls",
"version": "1.3",
"cipherSuites": [
{
"name": "TLS_AES_256_GCM_SHA384",
"algorithms": [
"algorithm/aes-256-gcm",
"algorithm/sha-384"
],
"identifiers": [
"0x13,0x02"
],
"tlsGroups": [
"X25519MLKEM768"
],
"tlsSignatureSchemes": [
"rsa_pss_rsae_sha256"
]
}
],
"relatedCryptographicAssets": [
{
"type": "algorithm",
"ref": "algorithm/x25519mlkem768"
},
{
"type": "certificate",
"ref": "certificate/www-example-com"
}
]
}
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/x25519mlkem768",
"name": "X25519MLKEM768",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "combiner",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"keyderive"
]
}
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/ml-kem-768",
"name": "ML-KEM-768",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "ML-KEM",
"primitive": "kem",
"parameterSetIdentifier": "768",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"keygen",
"encapsulate",
"decapsulate"
],
"nistQuantumSecurityLevel": 3
},
"oid": "2.16.840.1.101.3.4.4.2"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/x25519",
"name": "x25519",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "ECDH",
"ellipticCurve": "other/Curve25519",
"primitive": "key-agree",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"keygen",
"keyderive"
],
"nistQuantumSecurityLevel": 0
},
"oid": "1.3.101.110"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/aes-256-gcm",
"name": "AES-256-GCM",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "AES",
"primitive": "ae",
"parameterSetIdentifier": "256",
"mode": "gcm",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"encrypt",
"decrypt",
"tag"
],
"classicalSecurityLevel": 256,
"nistQuantumSecurityLevel": 5
},
"oid": "2.16.840.1.101.3.4.1.46"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/sha-384",
"name": "SHA-384",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "SHA-2",
"primitive": "hash",
"parameterSetIdentifier": "384",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"digest"
]
},
"oid": "2.16.840.1.101.3.4.2.2"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "certificate/www-example-com",
"name": "www.example.com",
"cryptoProperties": {
"assetType": "certificate",
"certificateProperties": {
"serialNumber": "4F2A9C1E7B30D85A",
"subjectName": "CN = www.example.com",
"issuerName": "CN = Example Issuing CA, O = Example Ltd, C = GB",
"notValidBefore": "2026-09-01T00:00:00Z",
"notValidAfter": "2027-03-01T23:59:59Z",
"certificateFormat": "X.509",
"certificateFileExtension": "pem",
"certificateState": [
{
"state": "active"
}
],
"relatedCryptographicAssets": [
{
"type": "algorithm",
"ref": "algorithm/rsa-pkcs1-1.5-sha-256-2048"
},
{
"type": "publicKey",
"ref": "key/www-example-com-rsa-2048"
}
]
}
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/rsa-pkcs1-1.5-sha-256-2048",
"name": "RSA-PKCS1-1.5-SHA-256-2048",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "RSASSA-PKCS1",
"primitive": "signature",
"parameterSetIdentifier": "2048",
"padding": "pkcs1v15",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"verify"
],
"classicalSecurityLevel": 112,
"nistQuantumSecurityLevel": 0
},
"oid": "1.2.840.113549.1.1.11"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "key/www-example-com-rsa-2048",
"name": "RSA-2048 public key, www.example.com",
"cryptoProperties": {
"assetType": "related-crypto-material",
"relatedCryptoMaterialProperties": {
"type": "public-key",
"state": "active",
"size": 2048,
"format": "DER"
},
"oid": "1.2.840.113549.1.1.1"
}
}
],
"dependencies": [
{
"ref": "algorithm/x25519mlkem768",
"dependsOn": [
"algorithm/ml-kem-768",
"algorithm/x25519"
]
}
]
}
What each part records:
- The protocol component.
protocolPropertiesrecords the protocol type and version, the cipher suite by name and by its IANA identifier (0x13,0x02), the negotiated key exchange group intlsGroups, and the handshake signature scheme intlsSignatureSchemes. The cipher suite’salgorithmslist points at the AES-256-GCM and SHA-384 components.relatedCryptographicAssetslinks the protocol to the hybrid group and to the certificate. - The hybrid group. X25519MLKEM768 is defined in RFC 10024, published in August 2026, which combines X25519 ECDH with ML-KEM-768. It is recorded as an algorithm with the primitive
combinerand adependsOnrelationship to its two parts. This is the pattern the CycloneDX guide uses for hybrid schemes. - The two halves. ML-KEM-768 is in NIST security category 3, as stated in FIPS 203, so it carries
nistQuantumSecurityLevel3. X25519 carries 0. No level is set on the combiner itself: an assessor reads the levels of its parts, and the protection against a future quantum attack comes from the ML-KEM half. - The certificate.
certificatePropertiesrecords subject, issuer, validity dates and state, and links to the signature algorithm and the public key. The signature is RSA PKCS#1 v1.5 with SHA-256, at a classical strength of 112 bits (NIST SP 800-57 Part 1, Table 2) andnistQuantumSecurityLevel0. - Two RSA signature types. The certificate is signed with PKCS#1 v1.5, while the handshake uses
rsa_pss_rsae_sha256. TLS 1.3 requires this split. RFC 9846, the current TLS 1.3 specification, says the PKCS#1 v1.5 values “refer solely to signatures which appear in certificates”.
Reading it for quantum exposure. The key exchange is hybrid, so recorded traffic from this endpoint is protected against later decryption by a quantum computer for as long as ML-KEM-768 holds. The authentication is not. Certificate and handshake signatures both rely on RSA-2048. The record shows the split plainly: the key exchange has moved to post-quantum protection, and the signatures have not. The validity dates matter too. In the guide’s words, “An RSA certificate expiring in one week poses less cryptographic risk than the same certificate expiring in 20 years.”
Example 2: an application, a library and the algorithms it uses
A payments service encrypts stored tokens with AES-256-GCM and wraps data keys with RSA-OAEP. Both algorithms come from a cryptographic library, and source code assessment found the call site.
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"version": 1,
"components": [
{
"type": "application",
"bom-ref": "app/payments-service",
"name": "payments-service",
"version": "4.2.0",
"evidence": {
"occurrences": [
{
"location": "src/main/java/com/example/payments/TokenVault.java",
"line": 87,
"symbol": "Cipher.getInstance"
}
]
}
},
{
"type": "library",
"bom-ref": "lib/example-crypto-library",
"name": "example-crypto-library",
"version": "2.4.1"
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/aes-256-gcm",
"name": "AES-256-GCM",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "AES",
"primitive": "ae",
"parameterSetIdentifier": "256",
"mode": "gcm",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"encrypt",
"decrypt",
"tag"
],
"classicalSecurityLevel": 256,
"nistQuantumSecurityLevel": 5
},
"oid": "2.16.840.1.101.3.4.1.46"
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/rsa-oaep-sha-256-2048",
"name": "RSA-OAEP-SHA-256-2048",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "RSAES-OAEP",
"primitive": "pke",
"parameterSetIdentifier": "2048",
"padding": "oaep",
"executionEnvironment": "software-plain-ram",
"cryptoFunctions": [
"encrypt",
"decrypt"
],
"classicalSecurityLevel": 112,
"nistQuantumSecurityLevel": 0
},
"oid": "1.2.840.113549.1.1.7"
}
}
],
"dependencies": [
{
"ref": "app/payments-service",
"dependsOn": [
"lib/example-crypto-library",
"algorithm/aes-256-gcm",
"algorithm/rsa-oaep-sha-256-2048"
]
},
{
"ref": "lib/example-crypto-library",
"provides": [
"algorithm/aes-256-gcm",
"algorithm/rsa-oaep-sha-256-2048"
]
}
]
}
- Evidence. The application component carries an
evidence.occurrencesentry with the file, line and symbol where the cryptography was found. That is what lets an engineer go straight to the code that needs changing. providesanddependsOntogether. The libraryprovidesboth algorithms, which says only that it implements them. The applicationdependsOnboth algorithms, which says they are in use. A library that provides fifty algorithms does not create fifty migration items. The application’s actual use creates two.- The algorithms. AES-256-GCM is recorded with mode
gcm, a classical strength of 256 bits andnistQuantumSecurityLevel5, the category defined by AES-256 key search. RSA-OAEP-SHA-256-2048 is recorded with paddingoaep, 112 bits classical and level 0.
Reading it for quantum exposure. The symmetric layer can stay. The RSA-OAEP key wrapping is the migration item, and because it protects keys for stored data, it is also a harvest-now-decrypt-later concern: anyone holding a copy of the wrapped keys could unwrap them once RSA-2048 falls.
Example 3: a code signing key held in an HSM
A code signing key lives in a hardware security module and signs releases with RSA-PSS.
{
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"version": 1,
"components": [
{
"type": "device",
"bom-ref": "device/example-hsm-01",
"name": "example-hsm-01",
"version": "7.1"
},
{
"type": "cryptographic-asset",
"bom-ref": "key/code-signing-2026",
"name": "Code signing key 2026",
"cryptoProperties": {
"assetType": "related-crypto-material",
"relatedCryptoMaterialProperties": {
"type": "private-key",
"id": "code-signing-2026",
"state": "active",
"size": 3072,
"creationDate": "2026-01-12T09:00:00Z",
"activationDate": "2026-01-15T00:00:00Z",
"expirationDate": "2029-01-15T00:00:00Z",
"securedBy": {
"mechanism": "HSM"
},
"relatedCryptographicAssets": [
{
"type": "algorithm",
"ref": "algorithm/rsa-pss-sha-256-3072"
}
]
}
}
},
{
"type": "cryptographic-asset",
"bom-ref": "algorithm/rsa-pss-sha-256-3072",
"name": "RSA-PSS-SHA-256-3072",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"algorithmFamily": "RSASSA-PSS",
"primitive": "signature",
"parameterSetIdentifier": "3072",
"executionEnvironment": "hardware",
"certificationLevel": [
"fips140-3-l3"
],
"cryptoFunctions": [
"sign"
],
"classicalSecurityLevel": 128,
"nistQuantumSecurityLevel": 0
},
"oid": "1.2.840.113549.1.1.10"
}
}
],
"dependencies": [
{
"ref": "device/example-hsm-01",
"provides": [
"algorithm/rsa-pss-sha-256-3072"
]
}
]
}
- The key. The key is recorded as
related-crypto-materialof typeprivate-key, with size, dates and astate. The schema defines state as “The key state as defined by NIST SP 800-57.”securedByrecords the HSM as the protection mechanism. - No key material. The schema has a
valuefield. For a private key, leave it out. A CBOM is an inventory of metadata and is shared more widely than the keys it describes. - The algorithm. RSA-PSS-SHA-256-3072 is recorded with
executionEnvironmentset tohardware, a certification level, a classical strength of 128 bits (SP 800-57 Part 1, Table 2) andnistQuantumSecurityLevel0. The HSM device componentprovidesthe algorithm.
Reading it for quantum exposure. Signatures are not exposed to harvest now, decrypt later in the way encrypted data is. A forged signature needs a quantum computer at the time of the forgery. What makes this key a priority is its reach and its lifetime: it expires in 2029, and software it signs may be verified long after that. Knowing that it sits in an HSM with a recorded certification level also tells the migration team that the HSM’s own post-quantum support is a prerequisite.
The three examples at a glance
| Asset | NIST quantum level | Reading |
|---|---|---|
| ML-KEM-768 (in X25519MLKEM768) | 3 | Post-quantum key exchange in place |
| X25519 (in X25519MLKEM768) | 0 | Classical half of the hybrid |
| AES-256-GCM | 5 | Symmetric, can stay |
| RSA-2048 certificate signature | 0 | Authentication still to migrate |
| RSA-OAEP-SHA-256-2048 | 0 | Key wrapping to migrate, stored-data exposure |
| RSA-PSS-SHA-256-3072 in HSM | 0 | Long-lived signing key to migrate, HSM support is a prerequisite |
Common mistakes when writing a CBOM
- Free-text algorithm and curve names. Use the CycloneDX registry values for
algorithmFamilyandellipticCurve, such asECDHandother/Curve25519, rather than whatever string a tool printed. - Unchecked OIDs. Object identifiers are easy to copy wrongly. Check them against the registry that assigned them: NIST’s Computer Security Objects Register for AES, SHA-2, ML-KEM and ML-DSA, RFC 8017 for RSA, and RFC 8410 for X25519. If you cannot confirm an OID, omit the field rather than guess.
- Treating
providesas use. An inventory built only from what libraries implement overstates the work. Record use withdependsOn. - Guessing. Most of the enumerations in the cryptographic properties, such as
primitive,modeandexecutionEnvironment, includeunknown. A recorded unknown can be followed up, but a guess hides the gap. - Secrets in the BOM. Record that a key exists and how it is protected, not its value.
- Skipping validation. The schema enforces the registry values. A CBOM that fails validation will fail in the tools that consume it.
Where CBOM requirements are heading
In the US, OMB memorandum M-26-15 says an agency’s automated cryptographic inventory “should populate a central Cryptographic Bill of Materials (CBOM)”. Executive Order 14412 directs CISA, in coordination with NIST, to publish guidance on the minimum elements of a CBOM, due about 270 days after the order, around 19 March 2027. Until that guidance exists, CycloneDX is the published format to build on. The examples in this post will need checking against those minimum elements once they are released. See what OMB M-26-15 and EO 14412 mean for suppliers for the full timeline.
How a CBOM feeds the ECEM lifecycle
Enterprise Cryptographic Exposure Management (ECEM) is a continuous six-stage lifecycle: Discover, Inventory, Assess, Prioritise, Transition, Monitor. A CBOM is the Inventory stage written down in a form machines can read. The fields in these examples feed the stages that follow it: security levels and certificate dates feed Assess, dependencies and evidence feed Prioritise by showing what is actually in use and where, and the same document regenerated over time feeds Monitor.
Quantum Sentinel builds a living Enterprise CBOM from discovery across the estate and exports it as CycloneDX 1.7. The examples in this post were written by hand to illustrate the format and are not Quantum Sentinel output. The cryptographic coverage page lists what the platform discovers.
Frequently asked questions
What does a CBOM example look like?
A CBOM in CycloneDX is a CycloneDX document, usually JSON, whose components include cryptographic assets. Each asset has a cryptoProperties block with an assetType of algorithm, certificate, protocol or related-crypto-material, plus properties such as algorithm family, parameter set, security levels and OID. Dependencies link assets to the applications, libraries and devices that use or provide them.
Which CycloneDX version supports CBOM?
CBOM was introduced in CycloneDX 1.6, released on 9 April 2024. CycloneDX 1.7, released on 21 October 2025, added standardised lists of algorithm families and elliptic curves. The current 1.7 patch release is 1.7.2.
How do you record hybrid key exchange such as X25519MLKEM768 in a CBOM?
Record each half as its own algorithm component, ML-KEM-768 and X25519, then record the hybrid as an algorithm with the primitive combiner and a dependsOn relationship to both halves. In a TLS protocol component, the hybrid group name also appears in the cipher suite’s tlsGroups list.
What does nistQuantumSecurityLevel 0 mean?
It means the algorithm meets none of NIST’s post-quantum security categories. RSA, ECDH, ECDSA and X25519 are recorded as 0. Post-quantum and symmetric algorithms are recorded by category, for example 3 for ML-KEM-768 and 5 for AES-256.
Should a CBOM contain private keys?
No. A CBOM should record that a key exists, its type, size, state, dates and how it is protected, for example in an HSM. The key material itself should stay where it is protected.
Sources: CycloneDX, specification and JSON schemas (release 1.7.2, including bom-1.7.schema.json and cryptography-defs.schema.json); OWASP CycloneDX, Authoritative Guide to CBOM; CycloneDX, v1.7 release announcement (21 October 2025) and v1.6 release announcement (9 April 2024); IETF, RFC 10024 and RFC 9846; IANA, TLS parameters; NIST, FIPS 203, post-quantum security categories, SP 800-57 Part 1 Rev. 5 and the Computer Security Objects Register.
Further reading: what a cryptography bill of materials is, how CBOM became part of CycloneDX, what Enterprise Cryptographic Exposure Management is and the Quantum Sentinel cryptographic coverage page.