Enterprise-Grade Cryptographic & Quantum Bill of Materials CLI JavaScript (Node.js) · CycloneDX 1.6 · CBOM + QBOM · Post-Quantum Ready
cbom performs comprehensive cryptographic discovery across source code, dependencies, container
images, compiled binaries, PKI/keystores, live key stores (Azure Key Vault, AWS KMS/ACM,
HashiCorp Vault), and live network endpoints, then emits both a CBOM (Cryptographic Bill
of Materials) and a companion QBOM (Quantum Bill of Materials) in CycloneDX 1.6 — with risk
scoring, post-quantum readiness analysis, compliance evaluation against ten frameworks (including
UNECE R155 and ISO/SAE 21434 for automotive), a custom policy engine, webhook
notifications, and a portfolio dashboard that rolls every project up into one CISO view.
The five pillars of enterprise cryptographic discovery (as in IBM's CBOM/QBOM tooling):
| Pillar | Status | How |
|---|---|---|
| 1. Source-code scanning (AST-level) | ✅ | Real syntax trees via web-tree-sitter (pure WASM) for JS/TS, Python, Java, Go, Ruby, PHP, C/C++, C#, Rust, Kotlin, Scala, Swift. Resolves import aliases, aliased objects, and propagated constants — catching what regex cannot (e.g. nodeCrypto.createCipheriv(ALGO,…)). Regex engine runs alongside as a fallback for every other language. |
| 2. Container / binary / dependency | ✅ | Dependency manifests (11 ecosystems + CVE DB); Dockerfile/compose crypto packages & baked-in keys; OCI / docker save image tarball layer walking (cbom image); ELF/PE/Mach-O/JAR crypto-library soname & banner detection. |
| 3. Certificate & PKI discovery | ✅ | X.509 PEM/DER/PKCS#12; JKS/keystore parsing; CA-bundle / trust-store analysis; per-file trust-chain validation (missing issuers); LDAP / Active Directory endpoint discovery. |
| 4. Network / protocol scanning | ✅ | Active probing (cbom netscan): TLS 1.0–1.3 version enumeration, negotiated cipher suite, served certificate chain; SSH KEXINIT algorithm enumeration; LDAP/LDAPS; IPsec/IKE reachability. Pure Node — no external binaries. |
| 5. Key & secret discovery (HSM/KMS/Vault) | ✅ | Provider-specific secret regexes + entropy; private-key files; PKCS#11 HSMs, AWS/Azure/GCP KMS, HashiCorp Vault / CyberArk, cloud HSMs, Java keystores. |
| 6. LIVE key-store connectors (metadata only) | ✅ | cbom vault azure|aws|hashicorp — enumerates key types, sizes, rotation, expiry and certificates directly from Azure Key Vault, AWS KMS + ACM, and HashiCorp Vault REST APIs with read-only credentials. Key material and secret values are never requested. Zero SDK dependencies. |
| 7. Portfolio / CISO roll-up | ✅ | cbom portfolio <dir> — aggregates every CBOM/QBOM (repos, vaults, endpoints, images) into one fleet dashboard: quantum-readiness heat map, harvest-now-decrypt-later register, expiring certificates, compliance verdicts, trends across scans. |
npm install -g precogs-cbomOr run locally:
git clone <repo>
cd cbom-engine
npm install
node ./bin/cbom.js scan ./your-projectRequires Node.js ≥ 18. No network calls during a scan — all CVE / PQC data is bundled.
# scan a project; emit JSON, Markdown, and HTML reports
cbom scan ./my-project --secrets-detect --pqc-check \
--compliance pci-dss,fips-140,nist-pqc \
--output cbom-report --fail-on criticalThis produces:
cbom-report.json— CycloneDX 1.6 CBOMcbom-report.qbom.json— CycloneDX 1.6 QBOM (quantum readiness) — suppress with--no-qbomcbom-report.md— human-readable findings reportcbom-report.html— interactive dashboard (open in a browser)
# also actively probe live endpoints and fold results into the same CBOM/QBOM
cbom scan ./my-project --targets targets.yaml
# deep-scan a container image tarball (docker save my:tag -o image.tar)
cbom image image.tar
# probe network endpoints only
cbom netscan targets.yaml
# LIVE-scan a managed key store (metadata only — read-only credentials)
cbom vault azure --vault-url https://myvault.vault.azure.net --project vehicle-line-x
cbom vault aws --region eu-west-2 --project vehicle-line-x # KMS + ACM
cbom vault hashicorp --address https://vault.corp:8200 # transit + pki
# evaluate your own crypto policy and notify a ticketing webhook
cbom scan ./my-project --policy jlr-baseline.yaml --fail-on-policy \
--webhook https://hooks.example.com/crypto --project ecu-gateway
# roll every CBOM/QBOM in a directory up into one CISO dashboard
cbom portfolio ./boms -o portfolio # → portfolio.html + portfolio.json
# run the QBOM Discovery API so ECUs/pipelines request QBOMs over REST
CBOM_API_TOKEN=secret cbom serve --port 8787 # the Post-Quantum Repository
# generate a CISO executive summary (offline, or --ai for a Claude narrative)
cbom summary portfolio.json -o exec-summary.md
cbom summary portfolio.json --ai -o exec-summary.md
# correlate crypto posture with the Armis asset inventory
cbom armis portfolio.json --url https://tenant.armis.com --secret $ARMIS_SECRET| Flag | Description | Default |
|---|---|---|
-o, --output <file> |
Output base path (extension auto-added) | cbom-report |
-f, --format <fmt> |
cyclonedx, markdown, html, or all |
all |
-c, --compliance <list> |
Comma-separated frameworks (see below) | none |
--pqc-check |
Enable post-quantum analysis section | always on |
--secrets-detect |
Enable hardcoded secret + entropy detection | off |
--targets <file> |
Also actively probe endpoints in a YAML/JSON targets file (TLS/SSH/LDAP/IPsec) | off |
--policy <file> |
Evaluate findings against a custom YAML/JSON crypto policy (see examples/policy.example.yaml) |
off |
--fail-on-policy |
Exit code 1 if any policy rule with severity FAIL matches | off |
--webhook <url> |
POST a JSON scan summary on completion (Jira/ServiceNow/SIEM; --webhook-style slack for chat) |
off |
--project <name> |
Project name recorded in the BOM — groups scans in cbom portfolio |
dir name |
--no-qbom |
Do not emit the companion QBOM alongside the CBOM | emit |
--exclude <patterns> |
Comma-separated glob patterns to skip | node_modules,dist,.git |
--min-risk <level> |
Lowest level to include: critical/high/medium/low/safe |
low |
--fail-on <level> |
Exit code 1 if findings at this level exist | critical |
--no-color |
Disable colored CLI output | on |
--json-summary |
Print a one-line JSON summary to stdout | off |
Additional commands:
cbom validate <cbom.json> # validates a CycloneDX 1.6 CBOM or QBOM file
cbom diff <cbomA.json> <cbomB.json> # shows added/removed components between scans
cbom tui <cbom.json> # open the interactive browser on a saved report
cbom netscan <targets.yaml> # actively probe TLS/SSH/LDAP/IPsec endpoints → CBOM+QBOM
cbom image <image.tar> # deep-scan an OCI / docker-save image tarball → CBOM+QBOM
cbom vault <azure|aws|hashicorp> # LIVE key-store scan (metadata only) → CBOM+QBOM
cbom pqr <dir|cbom.json> # Post-Quantum Repository — readiness reading + registry + migration simulator
cbom graph <dir|cbom.json> # exploitability engine — rank the findings that MATTER
cbom portfolio <dir> # aggregate all CBOM/QBOMs → CISO dashboard (HTML+JSON)
cbom serve # QBOM Discovery API (Post-Quantum Repository) → docs/API.md
cbom summary <file> # CISO executive summary (offline, or --ai) → docs/INTEGRATIONS.md
cbom armis <portfolio.json> # correlate crypto posture with Armis assets → docs/INTEGRATIONS.mdCBOM tells you what crypto you have; QBOM tells you what's quantum-vulnerable; the PQR is the migration authority that turns "you're not ready" into a plan: a readiness reading (index + grade + runway to the CNSA 2.0 2035 deadline + a harvest-now-decrypt-later count), a browsable registry of NIST-standardized PQC algorithms (ML-KEM/FIPS 203, ML-DSA/FIPS 204, SLH-DSA/FIPS 205, LMS/XMSS, CNSA-2.0-approved flagged), per-family migration playbooks, and a migration simulator:
cbom pqr ./my-project # readiness + registry + full-migration projection
cbom pqr cbom-report.json --simulate RSA,ECDSA # "fix these → readiness jumps to X"The simulator produces the board line: "migrate RSA → readiness 8/100 (F) → 92/100 (A)", dependency-ordered into rollout waves, with a biggest-bang ranking of which family to fix first. Self-contained HTML + JSON. Every vulnerable finding links into the registry and its playbook.
A flat inventory of "here are your weak algorithms" is where IBM and AppviewX
stop. A real vehicle-platform CBOM has thousands of findings; RSA-2048 appears in
hundreds of places, most of them test fixtures that never touch a live interface.
cbom graph scores every finding by exploitability — a transparent weighted
model of intrinsic severity × reachability/exposure × data longevity (harvest-now-
decrypt-later) × blast radius — and builds an asset graph clustering findings
by shared root (same library, key, cert). The same critical AES-128-ECB scores
72 (HIGH) in an auth handler but 53 (MEDIUM) in a test fixture; a quantum-
vulnerable key on a live TLS path outranks a test-file critical. Output is a
ranked "fix these first" shortlist + an interactive HTML graph.
cbom graph ./my-project -o crypto-graph # scan + score → crypto-graph.html + .json
cbom graph cbom-report.json # score an existing CBOM post-hocEvery cbom scan also computes this automatically and persists it in the CBOM
(cbom:exploitability per component, cbom:exploitability:actNow roll-up), so
the portfolio dashboard, executive summary, and API all key off "the N that
matter" instead of a flat severity count. The model is documented and tunable —
weights are intrinsic·0.45 + exposure·0.30 + longevity·0.15 + blast·0.10.
A pure-Node REST service (no web framework, zero new deps) that exposes the
engine so 100–200 ECUs / CI pipelines can request QBOMs on demand instead of
running the CLI. Bearer-token auth; every scan is persisted per project and
rolled up at GET /api/v1/portfolio. Register a project, then POST a source
tarball / firmware ELF / certificate, or point it at a live endpoint or vault:
CBOM_API_TOKEN=secret cbom serve --port 8787 --data-dir /var/lib/pqr
# POST /api/v1/projects → POST /api/v1/projects/:id/scan/firmware → GET .../qbomFull contract, ECU self-service flow, and Postgres-swap notes: docs/API.md.
Turns a CBOM/QBOM or a portfolio.json into a board-ready Markdown narrative.
Offline by default (deterministic, air-gapped — a real deliverable on its
own); --ai sends the same non-sensitive roll-up (counts, grades, finding
titles — never source or secrets) to the Claude API for a richer narrative and
falls back to offline if @anthropic-ai/sdk / ANTHROPIC_API_KEY is absent.
Correlates crypto posture with the Armis asset inventory — answering "which Armis-tracked ECUs run quantum-vulnerable crypto?" — and can push crypto risk back into the Armis console as device custom properties. Metadata-only REST. See docs/INTEGRATIONS.md.
Read-only, metadata-only discovery — key material and secret values are never requested,
and no cloud SDKs are bundled (pure-Node REST with SigV4/OAuth implemented in node:crypto):
| Provider | What is inventoried | Credentials |
|---|---|---|
azure |
Key Vault keys (kty, size, curve, HSM-backing, expiry, rotation policy) + certificates (subject, key spec, expiry) + secret count | --tenant-id/--client-id/--client-secret or AZURE_TENANT_ID/AZURE_CLIENT_ID/AZURE_CLIENT_SECRET + --vault-url |
aws |
Customer KMS keys (KeySpec, usage, origin incl. CloudHSM, state, rotation) + ACM certificates (key alg, sig alg, expiry, in-use) | Standard AWS_* env vars or flags + --region |
hashicorp |
Transit engine keys (type, versions/rotation, capabilities) + PKI mount issuance counts, via sys/mounts discovery |
VAULT_ADDR + VAULT_TOKEN or flags |
Every discovered key/cert is risk-scored (weak sizes, expiry, rotation posture) and PQC-classified (Shor/Grover, ML-KEM/ML-DSA migration target), then flows into the same CBOM/QBOM as static findings — so a vault scan, a repo scan, and a network scan aggregate into one portfolio.
Encode your organisation's crypto standard as YAML (exact names or /regex/; match on type,
detection surface, provider, PQC posture, risk level) — violations render in every output format and
in the CycloneDX metadata, and --fail-on-policy gates CI. See examples/policy.example.yaml.
Point it at a directory of CBOM/QBOM files (from any mix of scan / vault / netscan / image,
or third-party CycloneDX CBOMs). Groups by --project name, keeps the latest scan per project and
uses earlier ones for trends, then emits portfolio.html (quantum-readiness heat map,
harvest-now-decrypt-later register, expiring certificates ≤90 days, compliance verdicts, per-project
sparklines) and portfolio.json for programmatic consumption.
--targets and cbom netscan accept a YAML or JSON file. type is inferred from the port when omitted:
targets:
- host: api.jlr.example.com
port: 443
type: tls # tls | ssh | ldap | ldaps | ipsec
- host: git.internal
port: 22
type: ssh
- "ldaps://dc01.corp.jlr.local:636" # shorthand string form also worksActive probing is pure Node — it needs network reachability to the targets but no external tools
(openssl, nmap, ssh are not required). TLS enumerates versions 1.0–1.3, the negotiated cipher,
and the served certificate chain; SSH reads the cleartext KEXINIT to enumerate kex/host-key/cipher/MAC
algorithms; IPsec/IKE is a UDP/500 responder reachability check.
When stdout is a TTY, cbom scan automatically launches a multi-panel live dashboard
during the scan, then drops into an interactive findings browser when it completes.
| Key | Action |
|---|---|
↑ ↓ / j k |
navigate findings |
a c h m l s |
filter by severity (all/critical/high/medium/low/safe) |
t |
cycle type filter (algorithm/cert/key/protocol/library/secret) |
/ |
search by file or identifier (Esc clears) |
o |
open selected file in $EDITOR |
e |
export current filtered set → cbom-tui-export.json |
? |
help |
q / Ctrl-C |
quit |
Disable the TUI for CI / piped output with --no-tui. Disable just the post-scan browser
with --no-browser (live dashboard still runs).
Project-level ignore is also supported: drop a .cbomignore (gitignore-style) in your project root.
cbom v1.0.0 — Cryptographic Bill of Materials Engine
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✔ Scan complete — 9 files analyzed
✔ Algorithm Scanner — 8 findings (5 critical)
✔ Certificate Scanner — 3 findings (2 critical)
✔ Key Scanner — 1 findings (1 critical)
✔ Protocol Scanner — 9 findings (6 critical)
✔ Library Scanner — 5 findings (1 critical)
✔ Secret Scanner — 7 findings (4 critical)
✔ PQC Scanner — 5 vulnerable assets
╭───────────────────────────────────────────────────────────╮
│ OVERALL RISK SCORE: 0/100 F 🔴 │
│ 🔴 CRITICAL 20 findings │
│ 🟠 HIGH 6 findings │
│ 🟡 MEDIUM 4 findings │
│ 🟢 LOW 2 findings │
│ ⚛️ POST-QUANTUM: 5 vulnerable assets (HIGH RISK) │
│ Compliance: │
│ FAIL PCI DSS 4.0 │
│ FAIL FIPS 140-3 │
╰───────────────────────────────────────────────────────────╯
| Scanner | Detects |
|---|---|
| Algorithm (regex + AST) | AES variants & modes, DES/3DES/RC4/Blowfish/IDEA, RSA/DSA/ECC sizes, SHA family + MD5, HMAC variants, ChaCha20, Ed25519/X25519, PQC (ML-KEM, ML-DSA, SLH-DSA, FALCON). Regex across 10+ languages plus AST-level resolution (import aliases, aliased objects, constant propagation) via tree-sitter. |
| Container | Dockerfile/compose crypto packages, keys/certs baked into layers; OCI / docker save image tarball layer walking → crypto sonames, embedded keys & certs. |
| Binary | ELF / PE / Mach-O / JAR / .class / WASM — crypto library sonames & banners (OpenSSL/BoringSSL/GnuTLS/mbedTLS/wolfSSL/NSS/libsodium/BouncyCastle…) and weak-algorithm symbols. |
| PKI | JKS/keystore parsing, CA-bundle & trust-store analysis, per-file trust-chain validation, LDAP/LDAPS & Active Directory endpoint discovery. |
| KMS/HSM/Vault | PKCS#11 HSMs, AWS/Azure/GCP KMS, AWS Secrets Manager, HashiCorp Vault, CyberArk Conjur, cloud HSMs, Java keystores. |
| Network (active) | Live TLS version + cipher + cert-chain enumeration, SSH KEXINIT algorithm enumeration, LDAP/LDAPS, IPsec/IKE reachability. |
| Certificate | X.509 PEM/DER/P12 — expiry & 47-day mandate, self-signed, weak signatures (SHA-1/MD5), weak key sizes, SAN/EKU/CA flags. |
| Key | Private key files (PEM, OpenSSH, PKCS#8, GPG), file permissions, encryption status, hardcoded keys in source. |
| Protocol | TLS 1.0/1.1/SSLv2/SSLv3 detection in nginx/apache/IaC/source. Weak cipher suites (NULL, EXPORT, RC4, 3DES, anonymous). SSH algorithms (ssh-rsa, ssh-dss). HSTS configuration. |
| Library | Crypto dependencies + bundled CVE history (node-forge, jsonwebtoken, crypto-js, cryptography, PyJWT, pycrypto, openssl, bouncycastle, phpseclib, ring, etc.). |
| Secret | 25+ provider-specific token regexes (AWS, GitHub, Stripe, GCP, Slack, Twilio, etc.) plus Shannon-entropy detection on string literals. |
| PQC | Cross-references all findings against NIST FIPS 203/204/205. Migration priority ranking. CNSA 2.0 timeline. |
--compliance pci-dss,fips-140,hipaa,nist-pqc,cnsa-2,iso-27001,soc2,fedramp,unece-r155,iso-21434
| ID | Standard |
|---|---|
pci-dss |
PCI DSS 4.0 — Req 3.5.1, 4.2.1, 8.3.2, 6.4.3, 3.7 |
fips-140 |
NIST FIPS 140-3 approved algorithm enforcement |
hipaa |
HIPAA Security Rule 164.312, 164.308 |
nist-pqc |
NIST FIPS 203 (ML-KEM), 204 (ML-DSA), 205 (SLH-DSA) |
cnsa-2 |
NSA Commercial National Security Algorithm Suite 2.0 |
iso-27001 |
ISO/IEC 27001:2022 — Annex A cryptographic controls |
soc2 |
SOC 2 Trust Services Criteria (CC6.1, CC6.7, CC6.8, CC7.2) |
fedramp |
FedRAMP SC-13, SC-8, SC-12, IA-5 |
unece-r155 |
UNECE R155 (automotive CSMS) — Annex 5 cryptographic mitigations (M7/M10/M11/M12), cert lifecycle, vehicle-lifetime quantum risk |
iso-21434 |
ISO/SAE 21434 (road-vehicle cybersecurity) — Cl. 8 known weaknesses/CVEs, Cl. 10 secure design & key management, Cl. 13 emerging-threat monitoring |
{
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"serialNumber": "urn:uuid:3ea6c70e-921f-44af-8879-fc9e78c6b359",
"components": [
{
"type": "cryptographic-asset",
"bom-ref": "algo-...",
"name": "AES-128-ECB",
"cryptoProperties": {
"assetType": "algorithm",
"algorithmProperties": {
"primitive": "ae", "parameterSetIdentifier": "128",
"mode": "ecb", "padding": "unknown",
"cryptoFunctions": ["encrypt","decrypt"],
"classicalSecurityLevel": 128, "nistQuantumSecurityLevel": null
}
},
"evidence": { "occurrences": [{ "location": "auth.js", "line": 16 }] }
}
],
"vulnerabilities": [{ "id": "CWE-327", "ratings": [{ "severity": "high" }] }]
}Every CBOM scan also emits a companion QBOM (*.qbom.json) — the same CycloneDX 1.6 format viewed
through the post-quantum lens. Each cryptographic asset is annotated with:
qbom:quantumThreat—shor(public-key, fully broken),grover(symmetric/hash, halved), ornoneqbom:harvestNowDecryptLater— whether data protected today is exposed to future decryptionqbom:migrateTo/qbom:migrationStandard— concrete target (ML-KEM / FIPS 203, ML-DSA / FIPS 204, SLH-DSA / FIPS 205)nistQuantumSecurityLevelandclassicalSecurityLevelper algorithm
The QBOM metadata carries a quantum-readiness score/grade, per-family migration priority, a FIPS 203/204/205 mapping, and the CNSA 2.0 (2035) deadline reference.
Built to withstand enterprise security review:
| Concern | How it's addressed |
|---|---|
| Standards conformance | CBOM + QBOM validated against the official CycloneDX 1.6 JSON schema (bundled in schemas/), not a self-attested check. cbom validate <file> runs the real schema. |
| Detection accuracy | Labelled corpus + npm run bench computes precision / recall / F1 per category against ground truth, with a CI regression gate. Negative controls guard against false positives. |
| Unit tests | npm test (Node's built-in test runner) — algorithm classification, PQC rules, AST resolution, aggregation, JKS parsing, network target parsing, and schema-valid output. |
| CI integration | --format sarif emits SARIF 2.1.0 for GitHub code-scanning / any SARIF consumer. |
| Supply-chain | Dependencies pinned to exact versions; production surface is 0 critical / 0 high (npm audit --omit=optional); the TUI is an optional dependency so servers/CI carry no TUI-transitive advisories. Self-SBOM via npm run sbom. See SECURITY.md. |
npm test # unit tests
npm run bench # detection accuracy (precision/recall/F1)
npm run sbom # generate sbom.json (self-SBOM, schema-validated)
npm run audit # dependency auditAccuracy note: the bundled benchmark is a curated corpus proving the methodology and gating regressions — it is not a claim of a fixed real-world accuracy figure. Run
npm run benchagainst your own labelled corpus to measure precision/recall on your codebase before relying on the numbers in a contract.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ CLI │ ──▶ │ Engine │ ──▶ │ Aggregator │
│ commander │ │ scanner.js │ │ dedupe+rank │
└──────────────┘ └──────┬───────┘ └──────┬───────┘
│ │
┌───────────┴────────────┐ │
│ │ ▼
┌───────▼─────────┐ ┌──────▼─────┐ ┌──────────────┐
│ 7 Scanners │ │ Risk │ │ Output │
│ algorithm/cert/ │ │ Scorer + │ │ CycloneDX/ │
│ key/proto/lib/ │ │ PQC rules │ │ MD/HTML │
│ secret/pqc │ └────────────┘ └──────────────┘
└─────────────────┘
│
┌───────▼────────────────┐
│ data/*.json │
│ weak algos · PQC · │
│ secret regexes · CVEs │
└────────────────────────┘
| Code | Meaning |
|---|---|
0 |
Scan succeeded; no findings at or above --fail-on level |
1 |
Scan succeeded; findings present at the configured fail threshold |
2 |
Scan error (bad path, parse failure, etc.) |
Contributions welcome — see agent.md for the full design spec and roadmap.
PRs should:
- Add new findings to the appropriate
data/*.jsonrather than hardcoding rules in scanners. - Include a test fixture under
test/fixtures/exercising the new detection. - Document any new CLI flags in this README.
MIT © Precogs.ai