Introduction to CycloneDX CBOM
CycloneDX is the OWASP-maintained standard for Bill of Materials in cybersecurity. Version 1.6, released in 2024, formalized comprehensive support for Cryptographic Bill of Materials (CBOM) — providing a machine-readable format to represent cryptographic algorithms, protocols, certificates, keys, and implementations.
This technical guide covers everything you need to generate, validate, and consume CycloneDX CBOMs. Whether you’re building tooling, integrating CBOM into CI/CD pipelines, or evaluating CBOM solutions, this guide provides the structural knowledge required.
Why CycloneDX for CBOM?
| Feature | Benefit |
|---|---|
| Extensible data model | Native crypto component types without workarounds |
| Multiple serialization formats | JSON, XML, and Protobuf support |
| Ecosystem compatibility | Interoperates with existing CycloneDX SBOM tools |
| Active development | Continuous standard evolution with community input |
| Validation tooling | Schema-based validation ensures compliance |
| License | Open standard, no licensing restrictions |
CycloneDX CBOM Document Structure
Top-Level Schema
Every CycloneDX CBOM follows this top-level structure:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"metadata": {
"timestamp": "2026-06-10T10:00:00Z",
"tools": {
"components": [
{
"type": "application",
"name": "qcecuring-cbom",
"version": "2.1.0",
"publisher": "QCecuring"
}
]
},
"component": {
"type": "application",
"name": "target-system",
"version": "1.0.0"
}
},
"components": [],
"dependencies": [],
"compositions": []
}
Key Top-Level Fields
| Field | Required | Description |
|---|---|---|
bomFormat | Yes | Always “CycloneDX” |
specVersion | Yes | ”1.6” for CBOM support |
serialNumber | Recommended | UUID uniquely identifying this BOM instance |
version | Yes | Integer version of this BOM (increments with updates) |
metadata | Recommended | Generation context (tools, timestamp, subject) |
components | Yes | Array of cryptographic components |
dependencies | Optional | Relationships between components |
compositions | Optional | Completeness assertions |
Crypto Asset Types
CycloneDX v1.6 defines five primary cryptographic asset types:
1. Algorithm
Represents a specific cryptographic algorithm with its parameters:
{
"type": "crypto-asset",
"bom-ref": "crypto-algo-aes256gcm",
"name": "AES-256-GCM",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "ae",
"variant": "AES",
"parameterSetIdentifier": "256",
"mode": "gcm",
"padding": "none",
"cryptoFunctions": ["encrypt", "decrypt", "tag"],
"implementationPlatform": "software",
"certificationLevel": ["fips140-3-l1"],
"classicalSecurityLevel": 256,
"nistQuantumSecurityLevel": 5
},
"oid": "2.16.840.1.101.3.4.1.46"
}
}
Algorithm Primitives (the primitive field):
| Value | Description | Examples |
|---|---|---|
ae | Authenticated encryption | AES-GCM, ChaCha20-Poly1305 |
blockcipher | Block cipher | AES, Camellia |
streamcipher | Stream cipher | ChaCha20, RC4 |
hash | Hash function | SHA-256, SHA-384, SHA3-256 |
mac | Message authentication code | HMAC-SHA256, CMAC |
signature | Digital signature | ML-DSA, ECDSA, RSA-PSS |
kdf | Key derivation function | HKDF, PBKDF2, Argon2 |
kem | Key encapsulation mechanism | ML-KEM, RSA-KEM |
pke | Public key encryption | RSA-OAEP, ElGamal |
keyagree | Key agreement | ECDH, X25519, DH |
xof | Extendable output function | SHAKE128, SHAKE256 |
drbg | Random bit generator | CTR_DRBG, HMAC_DRBG |
2. Certificate
Represents an X.509 or other certificate:
{
"type": "crypto-asset",
"bom-ref": "crypto-cert-server-tls",
"name": "server.example.com TLS Certificate",
"cryptoProperties": {
"assetType": "certificate",
"certificateProperties": {
"subjectName": "CN=server.example.com,O=Example Corp",
"issuerName": "CN=Example Intermediate CA,O=Example Corp",
"notValidBefore": "2025-01-01T00:00:00Z",
"notValidAfter": "2026-12-31T23:59:59Z",
"signatureAlgorithmRef": "crypto-algo-ecdsa-p384",
"subjectPublicKeyRef": "crypto-key-server-ecdsa",
"certificateFormat": "X.509",
"certificateExtension": "pem"
}
}
}
Certificate Fields:
| Field | Description |
|---|---|
subjectName | Distinguished name of the certificate subject |
issuerName | Distinguished name of the issuing CA |
notValidBefore | Start of validity period |
notValidAfter | End of validity period |
signatureAlgorithmRef | Reference to the signing algorithm component |
subjectPublicKeyRef | Reference to the subject’s public key component |
certificateFormat | Format type (X.509, etc.) |
certificateExtension | File extension (pem, der, p12) |
3. Protocol
Represents a cryptographic protocol configuration:
{
"type": "crypto-asset",
"bom-ref": "crypto-proto-tls13",
"name": "TLS 1.3",
"cryptoProperties": {
"assetType": "protocol",
"protocolProperties": {
"type": "tls",
"version": "1.3",
"cipherSuites": [
{
"name": "TLS_AES_256_GCM_SHA384",
"algorithms": [
"crypto-algo-aes256gcm",
"crypto-algo-sha384"
],
"identifiers": ["0x13,0x02"]
},
{
"name": "TLS_CHACHA20_POLY1305_SHA256",
"algorithms": [
"crypto-algo-chacha20poly1305",
"crypto-algo-sha256"
],
"identifiers": ["0x13,0x03"]
}
],
"cryptoRefArray": [
"crypto-algo-x25519mlkem768",
"crypto-algo-ecdsa-p384"
]
}
}
}
4. Related Crypto Material
Represents keys, initialization vectors, nonces, seeds, and other cryptographic material:
{
"type": "crypto-asset",
"bom-ref": "crypto-key-server-ecdsa",
"name": "Server ECDSA Private Key",
"cryptoProperties": {
"assetType": "related-crypto-material",
"relatedCryptoMaterialProperties": {
"type": "private-key",
"id": "key-server-ecdsa-2025",
"state": "active",
"algorithmRef": "crypto-algo-ecdsa-p384",
"size": 384,
"format": "pkcs8",
"securedBy": {
"mechanism": "hsm",
"algorithmRef": "crypto-algo-aes256gcm"
},
"creationDate": "2025-01-15T00:00:00Z",
"activationDate": "2025-01-15T00:00:00Z",
"expirationDate": "2026-07-15T00:00:00Z"
}
}
}
Key Material Types:
| Value | Description |
|---|---|
private-key | Asymmetric private key |
public-key | Asymmetric public key |
secret-key | Symmetric secret key |
key-pair | Combined key pair |
ciphertext | Encrypted data |
signature | Digital signature value |
digest | Hash digest value |
initialization-vector | IV for symmetric encryption |
nonce | Cryptographic nonce |
seed | Random seed |
salt | Cryptographic salt |
shared-secret | Shared secret from key agreement |
tag | Authentication tag |
password | Password (for KDF input) |
5. Crypto Implementation
Represents a cryptographic library or hardware module:
{
"type": "crypto-asset",
"bom-ref": "crypto-impl-openssl",
"name": "OpenSSL",
"version": "3.2.1",
"cryptoProperties": {
"assetType": "crypto-implementation",
"cryptoImplementationProperties": {
"implementationType": "software",
"platform": "linux-x86_64",
"certificationLevel": ["fips140-3-l1"],
"certificationId": "CMVP #4282"
}
}
}
Quantum Readiness in CycloneDX CBOM
NIST Quantum Security Levels
CycloneDX supports quantum security level classification via the nistQuantumSecurityLevel field:
| Level | Equivalent Classical Security | Algorithms |
|---|---|---|
| 1 | AES-128 | ML-KEM-512, ML-DSA-44 |
| 2 | SHA-256 collision | — |
| 3 | AES-192 | ML-KEM-768, ML-DSA-65 |
| 4 | SHA-384 collision | — |
| 5 | AES-256 | ML-KEM-1024, ML-DSA-87 |
Marking Quantum Vulnerability
Algorithms can be annotated with quantum vulnerability information:
{
"type": "crypto-asset",
"bom-ref": "crypto-algo-rsa2048",
"name": "RSA-2048",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "pke",
"variant": "RSA",
"parameterSetIdentifier": "2048",
"classicalSecurityLevel": 112,
"nistQuantumSecurityLevel": 0
},
"oid": "1.2.840.113549.1.1.1"
},
"properties": [
{
"name": "quantumVulnerable",
"value": "true"
},
{
"name": "quantumAttack",
"value": "shors-algorithm"
},
{
"name": "cnsa2Compliant",
"value": "false"
}
]
}
Generating CycloneDX CBOMs
Method 1: QCecuring CBOM (Automated Enterprise Solution)
QCecuring CBOM generates comprehensive CycloneDX CBOMs automatically through multi-method discovery:
# Example: Generate CBOM for a target environment
qcecuring cbom generate \
--target production \
--output cbom-production.json \
--format cyclonedx \
--spec-version 1.6 \
--include-risk-scores \
--cnsa2-compliance-check
QCecuring handles the complexity of multi-source discovery (static analysis, binary scanning, network inspection, certificate enumeration) and produces validated CycloneDX output with enriched risk metadata.
Method 2: IBM CBOMkit (Open Source, Java Focused)
CBOMkit focuses on Java application analysis:
# Analyze a Java project
cbomkit scan --project ./my-java-app --output cbom.json
Limitations: Java-only, limited to static analysis, no network discovery.
Method 3: Manual Generation
For small-scale or custom implementations:
import json
from uuid import uuid4
from datetime import datetime
def generate_cbom(crypto_assets):
cbom = {
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": f"urn:uuid:{uuid4()}",
"version": 1,
"metadata": {
"timestamp": datetime.utcnow().isoformat() + "Z",
"tools": {
"components": [{
"type": "application",
"name": "custom-cbom-generator",
"version": "1.0.0"
}]
}
},
"components": crypto_assets
}
return cbom
# Example: Add an RSA-2048 algorithm component
rsa_component = {
"type": "crypto-asset",
"bom-ref": "crypto-rsa-2048-server",
"name": "RSA-2048",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "pke",
"variant": "RSA",
"parameterSetIdentifier": "2048",
"cryptoFunctions": ["encapsulate", "decapsulate"],
"classicalSecurityLevel": 112,
"nistQuantumSecurityLevel": 0
},
"oid": "1.2.840.113549.1.1.1"
}
}
cbom = generate_cbom([rsa_component])
print(json.dumps(cbom, indent=2))
Method 4: CI/CD Integration
Integrate CBOM generation into your build pipeline:
# GitHub Actions example
name: Generate CBOM
on:
push:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6am
jobs:
cbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run cryptographic analysis
run: |
qcecuring cbom generate \
--target ./src \
--output cbom.json \
--format cyclonedx
- name: Validate CBOM
run: |
cyclonedx validate --input cbom.json --spec-version 1.6
- name: Upload CBOM artifact
uses: actions/upload-artifact@v4
with:
name: cbom
path: cbom.json
- name: Check for quantum-vulnerable algorithms
run: |
qcecuring cbom check-policy \
--input cbom.json \
--policy no-quantum-vulnerable
Consuming CycloneDX CBOMs
Parsing and Analysis
import json
def analyze_cbom(cbom_path):
with open(cbom_path) as f:
cbom = json.load(f)
results = {
"total_assets": 0,
"quantum_vulnerable": [],
"quantum_safe": [],
"algorithms": [],
"certificates": [],
"protocols": []
}
for component in cbom.get("components", []):
if component.get("type") != "crypto-asset":
continue
results["total_assets"] += 1
crypto_props = component.get("cryptoProperties", {})
asset_type = crypto_props.get("assetType")
if asset_type == "algorithm":
algo_props = crypto_props.get("algorithmProperties", {})
quantum_level = algo_props.get("nistQuantumSecurityLevel", -1)
results["algorithms"].append({
"name": component["name"],
"bom_ref": component.get("bom-ref"),
"quantum_level": quantum_level,
"primitive": algo_props.get("primitive")
})
if quantum_level == 0:
results["quantum_vulnerable"].append(component["name"])
elif quantum_level > 0:
results["quantum_safe"].append(component["name"])
elif asset_type == "certificate":
results["certificates"].append(component["name"])
elif asset_type == "protocol":
results["protocols"].append(component["name"])
return results
# Usage
analysis = analyze_cbom("cbom-production.json")
print(f"Total crypto assets: {analysis['total_assets']}")
print(f"Quantum vulnerable: {len(analysis['quantum_vulnerable'])}")
print(f"Quantum safe: {len(analysis['quantum_safe'])}")
Integration with SBOM Tools
CycloneDX CBOMs integrate with the broader SBOM ecosystem:
Dependency Track (OWASP):
- Import CBOM alongside SBOM
- Correlate crypto components with software dependencies
- Track quantum vulnerability as a risk metric
GUAC (Google):
- Ingest CBOM data into supply chain graph
- Query relationships between software and cryptographic components
- Enable graph-based risk analysis
Grype / Trivy:
- Extend vulnerability scanning to include cryptographic weaknesses
- Alert on deprecated or quantum-vulnerable algorithms
- Policy enforcement for cryptographic standards
XML Format Example
CycloneDX CBOM in XML:
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
version="1">
<metadata>
<timestamp>2026-06-10T10:00:00Z</timestamp>
<tools>
<components>
<component type="application">
<name>qcecuring-cbom</name>
<version>2.1.0</version>
<publisher>QCecuring</publisher>
</component>
</components>
</tools>
</metadata>
<components>
<component type="crypto-asset" bom-ref="crypto-mlkem1024">
<name>ML-KEM-1024</name>
<cryptoProperties>
<assetType>algorithm</assetType>
<algorithmProperties>
<primitive>kem</primitive>
<variant>ML-KEM</variant>
<parameterSetIdentifier>1024</parameterSetIdentifier>
<cryptoFunctions>
<cryptoFunction>encapsulate</cryptoFunction>
<cryptoFunction>decapsulate</cryptoFunction>
</cryptoFunctions>
<classicalSecurityLevel>256</classicalSecurityLevel>
<nistQuantumSecurityLevel>5</nistQuantumSecurityLevel>
</algorithmProperties>
<oid>2.16.840.1.101.3.4.4.3</oid>
</cryptoProperties>
</component>
<component type="crypto-asset" bom-ref="crypto-rsa2048-legacy">
<name>RSA-2048</name>
<cryptoProperties>
<assetType>algorithm</assetType>
<algorithmProperties>
<primitive>pke</primitive>
<variant>RSA</variant>
<parameterSetIdentifier>2048</parameterSetIdentifier>
<cryptoFunctions>
<cryptoFunction>encapsulate</cryptoFunction>
<cryptoFunction>decapsulate</cryptoFunction>
<cryptoFunction>sign</cryptoFunction>
<cryptoFunction>verify</cryptoFunction>
</cryptoFunctions>
<classicalSecurityLevel>112</classicalSecurityLevel>
<nistQuantumSecurityLevel>0</nistQuantumSecurityLevel>
</algorithmProperties>
<oid>1.2.840.113549.1.1.1</oid>
</cryptoProperties>
</component>
<component type="crypto-asset" bom-ref="crypto-proto-tls13">
<name>TLS 1.3 Configuration</name>
<cryptoProperties>
<assetType>protocol</assetType>
<protocolProperties>
<type>tls</type>
<version>1.3</version>
<cipherSuites>
<cipherSuite>
<name>TLS_AES_256_GCM_SHA384</name>
<algorithms>
<algorithm ref="crypto-algo-aes256gcm"/>
<algorithm ref="crypto-algo-sha384"/>
</algorithms>
</cipherSuite>
</cipherSuites>
</protocolProperties>
</cryptoProperties>
</component>
</components>
</bom>
CBOM Validation
Schema Validation
CycloneDX provides JSON Schema and XML Schema for validation:
# Using CycloneDX CLI
cyclonedx validate --input cbom.json --spec-version 1.6
# Using ajv (JSON Schema validator)
npx ajv validate -s cyclonedx-bom-1.6.schema.json -d cbom.json
# Using xmllint (XML Schema validator)
xmllint --schema bom-1.6.xsd cbom.xml --noout
Semantic Validation
Beyond schema compliance, validate semantic correctness:
- Reference integrity: All
bom-refvalues referenced by other components must exist - Algorithm consistency: Parameter sets must match the algorithm variant
- Certificate chain validity: Issuer references should resolve to valid CA components
- OID accuracy: Object identifiers must match the described algorithm
- Date consistency: Certificate validity dates must be logical (notBefore < notAfter)
Policy Validation
Validate CBOM against organizational policies:
def validate_policy(cbom, policy):
violations = []
for component in cbom["components"]:
if component.get("type") != "crypto-asset":
continue
crypto_props = component.get("cryptoProperties", {})
if crypto_props.get("assetType") == "algorithm":
algo_props = crypto_props.get("algorithmProperties", {})
# Check minimum quantum security level
quantum_level = algo_props.get("nistQuantumSecurityLevel", 0)
if quantum_level < policy.get("min_quantum_level", 0):
violations.append({
"component": component["name"],
"violation": "Below minimum quantum security level",
"current": quantum_level,
"required": policy["min_quantum_level"]
})
# Check banned algorithms
variant = algo_props.get("variant", "")
if variant in policy.get("banned_algorithms", []):
violations.append({
"component": component["name"],
"violation": f"Banned algorithm: {variant}",
"remediation": policy.get("remediation_guidance", {}).get(variant)
})
return violations
# Example policy
policy = {
"min_quantum_level": 1, # No quantum-vulnerable algorithms
"banned_algorithms": ["DES", "3DES", "RC4", "MD5"],
"remediation_guidance": {
"RSA": "Migrate to ML-KEM-1024 for key exchange, ML-DSA-87 for signatures",
"DES": "Migrate to AES-256-GCM",
"MD5": "Migrate to SHA-384 or SHA-512"
}
}
Complete CBOM Example: Web Application
A comprehensive CBOM for a typical web application:
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"version": 1,
"metadata": {
"timestamp": "2026-06-10T14:30:00Z",
"tools": {
"components": [{
"type": "application",
"name": "qcecuring-cbom",
"version": "2.1.0"
}]
},
"component": {
"type": "application",
"name": "example-web-app",
"version": "3.2.0"
}
},
"components": [
{
"type": "crypto-asset",
"bom-ref": "impl-openssl",
"name": "OpenSSL",
"version": "3.2.1",
"cryptoProperties": {
"assetType": "crypto-implementation",
"cryptoImplementationProperties": {
"implementationType": "software",
"platform": "linux-x86_64",
"certificationLevel": ["fips140-3-l1"]
}
}
},
{
"type": "crypto-asset",
"bom-ref": "algo-tls-kex",
"name": "X25519MLKEM768",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "kem",
"variant": "hybrid",
"cryptoFunctions": ["encapsulate", "decapsulate"],
"classicalSecurityLevel": 128,
"nistQuantumSecurityLevel": 3
}
}
},
{
"type": "crypto-asset",
"bom-ref": "algo-aes256gcm",
"name": "AES-256-GCM",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "ae",
"variant": "AES",
"parameterSetIdentifier": "256",
"mode": "gcm",
"classicalSecurityLevel": 256,
"nistQuantumSecurityLevel": 5
},
"oid": "2.16.840.1.101.3.4.1.46"
}
},
{
"type": "crypto-asset",
"bom-ref": "proto-tls13",
"name": "TLS 1.3 (Hybrid PQC)",
"cryptoProperties": {
"assetType": "protocol",
"protocolProperties": {
"type": "tls",
"version": "1.3",
"cipherSuites": [{
"name": "TLS_AES_256_GCM_SHA384",
"algorithms": ["algo-aes256gcm"],
"identifiers": ["0x13,0x02"]
}],
"cryptoRefArray": ["algo-tls-kex"]
}
}
},
{
"type": "crypto-asset",
"bom-ref": "cert-server-tls",
"name": "*.example.com TLS Certificate",
"cryptoProperties": {
"assetType": "certificate",
"certificateProperties": {
"subjectName": "CN=*.example.com,O=Example Corp",
"issuerName": "CN=DigiCert TLS Hybrid RSA4096 SHA384 2022 CA1",
"notValidBefore": "2026-01-01T00:00:00Z",
"notValidAfter": "2027-01-01T00:00:00Z",
"signatureAlgorithmRef": "algo-ecdsa-p384",
"subjectPublicKeyRef": "key-server-ecdsa",
"certificateFormat": "X.509",
"certificateExtension": "pem"
}
}
},
{
"type": "crypto-asset",
"bom-ref": "key-server-ecdsa",
"name": "Server ECDSA P-384 Key",
"cryptoProperties": {
"assetType": "related-crypto-material",
"relatedCryptoMaterialProperties": {
"type": "private-key",
"state": "active",
"algorithmRef": "algo-ecdsa-p384",
"size": 384,
"securedBy": {
"mechanism": "software",
"algorithmRef": "algo-aes256gcm"
}
}
}
}
],
"dependencies": [
{
"ref": "proto-tls13",
"dependsOn": ["algo-tls-kex", "algo-aes256gcm", "cert-server-tls"]
},
{
"ref": "cert-server-tls",
"dependsOn": ["key-server-ecdsa", "algo-ecdsa-p384"]
}
]
}
Best Practices
1. Use Meaningful bom-ref Values
Reference identifiers should be human-readable and follow a consistent naming convention:
✓ crypto-algo-aes256gcm-server1
✓ crypto-cert-tls-production-2026
✓ crypto-key-hmac-api-signing
✗ component-1
✗ abc123
✗ ref_001
2. Include Complete Dependency Graphs
Map relationships between components to enable impact analysis:
- Protocol → uses → algorithms, certificates
- Certificate → signed-by → algorithm, key
- Key → protected-by → encryption algorithm
3. Enrich with Custom Properties
Use the properties array for organization-specific metadata:
{
"properties": [
{"name": "system-owner", "value": "platform-team"},
{"name": "environment", "value": "production"},
{"name": "migration-status", "value": "planned-q3-2026"},
{"name": "hndl-risk-score", "value": "critical"},
{"name": "cnsa2-compliant", "value": "false"}
]
}
4. Maintain CBOM Versioning
Increment the BOM version field with each update and maintain historical versions for tracking migration progress.
5. Validate Before Publishing
Always validate CBOMs against the CycloneDX schema before storage or transmission. Invalid CBOMs will fail to parse in downstream tools.
Key Takeaways
- CycloneDX v1.6 is the standard for CBOM — machine-readable, extensible, ecosystem-compatible
- Five crypto asset types cover all needs — algorithm, certificate, protocol, related crypto material, implementation
- JSON and XML are both fully supported — choose based on your tooling ecosystem
- Quantum readiness is built into the format —
nistQuantumSecurityLevelenables automated quantum risk assessment - Automated generation is essential — manual CBOM creation doesn’t scale; use QCecuring CBOM for enterprise environments
- Validation ensures interoperability — schema validation plus semantic checks ensure CBOM quality
- Integration with SBOM tools multiplies value — CycloneDX’s unified format enables cross-BOM analysis
- Dependencies capture relationships — essential for impact analysis and migration planning
- CI/CD integration enables continuous monitoring — CBOM generation should be automated and recurring
- The standard continues evolving — stay current with CycloneDX releases for new capabilities