CycloneDX dependency-reference audit
Audit local CycloneDX 1.6 bom-ref declarations and dependency edges, showing duplicates, dangling references, external URNs and unambiguous cycles.
- 1Add input
- 2Adjust settings
- 3Get your result
Tool input and files are processed in this browser without being uploaded.
Before you start
Inspect a generated SBOM before handing it to another system. Find cross-record reference problems that ordinary JSON syntax checks cannot explain, while retaining the complete original document.
How to use this tool
- Open or paste a CycloneDX 1.6 SBOM exported by your build.
- Check every duplicate path, unresolved edge and SCC; check whether a root was explicitly declared.
- Download complete reference reports and original.json, then repair the generator and rerun.
Supported inputs and limits
One UTF-8 JSON file or paste up to 5 MiB; 10,000 bom-ref declarations, 50,000 declared dependsOn edges, 200,000 JSON values and depth 64. Selected file takes precedence. All downloads combined up to 10 MiB; a large complete report can reach this cap before a count cap and then rejects atomically. Preview first 200 rows.
Supports CycloneDX JSON 1.6 only, with basic component/service/dependency shape checks, not complete official schema certification. Nested components/services and metadata.component are recognized. Every bom-ref declaration anywhere in the original is indexed with its JSON pointer. Other objects are not component/service graph targets. Version 1.4/1.5 reject.
Duplicate bom-ref declarations report every original path; their edges are excluded instead of overwriting an object. Duplicate dependency ref rows are explicit and all of those source edges are excluded. Repeated targets within a single dependency row remain visible as duplicate_edge. Missing local references, wrong target kind and unresolved external urn:cdx references are distinct.
SCC/self-loop analysis uses unambiguous internal component/service edges only. Reachability needs an explicit, unique metadata.component bom-ref; no first-component guess. The original JSON bytes, including precise numeric tokens and fields outside graph scope, remain in original.json. provides, compositions, formulation and vulnerabilities are preserved but not analysed. No network resolution, vulnerability scan or compliance verdict.
The result text and copy action use a compact preview when the report exceeds 20,000 characters. Complete report.json, CSV and HTML are downloaded artifacts. Long table cells show only their first 2,000 characters plus ellipsis; complete downloads are not truncated.
Worked example
Example input
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"component": {
"type": "application",
"name": "app",
"bom-ref": "app"
}
},
"components": [
{
"type": "library",
"name": "A",
"bom-ref": "A"
},
{
"type": "library",
"name": "B",
"bom-ref": "B"
}
],
"dependencies": [
{
"ref": "app",
"dependsOn": [
"A"
]
},
{
"ref": "A",
"dependsOn": [
"B"
]
},
{
"ref": "B",
"dependsOn": [
"A",
"missing",
"urn:cdx:11111111-1111-4111-8111-111111111111/1#remote"
]
}
]
}Example options
{"secondary":"","params":{"spreadsheetSafe":true}}Example output
{"format":"CycloneDX JSON 1.6 dependency audit","summary":{"declarations":3,"duplicateRefs":0,"dependencyDeclarations":3,"duplicateDependencyRefs":0,"edges":5,"resolvedEdges":3,"unresolvedEdges":2,"cycles":1,"rootStatus":"resolved","reachable":3,"unreachable":0},"definitions":[{"ref":"app","path":"/metadata/component/bom-ref","kind":"component","name":"app"},{"ref":"A","path":"/components/0/bom-ref","kind":"component","name":"A"},{"ref":"B","path":"/components/1/bom-ref","kind":"component","name":"B"}],"duplicates":[],"dependencyDeclarations":[{"ref":"app","path":"/dependencies/0/ref","status":"resolved","providesPreservedOutsideScope":false},{"ref":"A","path":"/dependencies/1/ref","status":"resolved","providesPreservedOutsideScope":false},{"ref":"B","path":"/dependencies/2/ref","status":"resolved","providesPreservedOutsideScope":false}],"duplicateDependencyRefs":[],"edges":[{"from":"app","to":"A","path":"/dependencies/0/dependsOn/0","status":"resolved"},{"from":"A","to":"B","path":"/dependencies/1/dependsOn/0","status":"resolved"},{"from":"B","to":"A","path":"/dependencies/2/dependsOn/0","status":"resolved"},{"from":"B","to":"missing","path":"/dependencies/2/dependsOn/1","status":"dangling_local"},{"from":"B","to":"urn:cdx:11111111-1111-4111-8111-111111111111/1#remote","path":"/dependencies/2/dependsOn/2","status":"external_urn_unresolved"}],"cycles":[["A","B"]],"reachability":{"rootRef":"app","rootStatus":"resolved","reachable":["A","B","app"],"unreachable":[]},"preservedOutsideScope":["provides","compositions","formulation","vulnerabilities","other non-dependency relationships"]}When something does not work
Use a supported 1.6 export. Give every declaration a unique bom-ref, fix dependency targets and duplicated dependency rows in the generator, and provide an explicit metadata root when reachability is needed. Keep external BOM links in their own workflow. Reduce input if full downloads exceed 10 MiB, then rerun.
Frequently asked questions
Can valid JSON Schema still contain duplicate references?
Yes. Cross-record reference uniqueness and dependency connections require semantic inspection. This report supplements a producer schema check.
Are all cycles invalid or insecure?
No. SCCs show declared dependency cycles only. The report does not decide whether a cycle is invalid, exploitable or compliant.
Why is root reachability unavailable?
A unique metadata.component bom-ref is required. Without it, the tool does not guess a root from array order.
Documentation & further reading
Related tools
JSON formatting workspace
Format or minify strict JSON, sort object keys, and encode or decode strings while preserving raw number tokens.
Regex tester
Try a pattern and see what it matches in your text.
Compare text
See what changed, side by side.
HTML formatter
Format HTML indentation so its structure is easier to read.