BOM Audit

June 20, 2026 · View on GitHub

cdxgen includes a built-in, post-generation BOM audit engine that evaluates your CycloneDX SBOM against a set of security and supply-chain rules. The engine uses JSONata expressions to query the BOM structure and YAML rule files to define what constitutes a finding.

Quick start

# Generate an SBOM with audit findings
cdxgen -o bom.json --bom-audit

# Audit with only CI permission rules
cdxgen -o bom.json --bom-audit --bom-audit-categories ci-permission

# Audit an Electron ASAR release artifact
cdxgen -t asar -o bom.json --bom-audit --bom-audit-categories asar-archive /absolute/path/to/app.asar

# Audit an offline rootfs for hardening drift
cdxgen /absolute/path/to/rootfs -t rootfs -o bom.json --bom-audit --bom-audit-categories rootfs-hardening

# Generate and audit a host HBOM with the built-in HBOM rule packs
cdxgen -t hbom -o hbom.json --bom-audit .

# Generate and audit an AI/ML BOM with the preferred AI-BOM alias
cdxgen -r --include-formulation -o aibom.json --bom-audit --bom-audit-categories ai-bom .

# Audit only the security-focused HBOM rules
cdxgen -t hbom -o hbom.json --bom-audit --bom-audit-categories hbom-security .

# Generate and audit a merged HBOM + OBOM host view
cdxgen -t hbom --include-runtime -o host-view.json --bom-audit .

# Audit only the host-topology correlation rules
cdxgen -t hbom --include-runtime -o host-view.json --bom-audit --bom-audit-categories host-topology .

# Audit a previously generated HBOM with the full HBOM alias pack
cdx-audit --bom hbom.json --direct-bom-audit --categories hbom

# Re-audit a saved AI-BOM later
cdx-audit --bom aibom.json --direct-bom-audit --categories ai-bom

# Audit with high-severity findings only
cdxgen -o bom.json --bom-audit --bom-audit-min-severity high

# Add your own rules directory
cdxgen -o bom.json --bom-audit --bom-audit-rules-dir ./my-rules

# Predictive audit only required npm/PyPI dependencies
cdxgen -o bom.json --bom-audit --bom-audit-scope required

# Include packages that already have trusted publishing metadata
cdxgen -o bom.json --bom-audit --bom-audit-include-trusted

# Audit only trusted-publishing-backed packages
cdxgen -o bom.json --bom-audit --bom-audit-only-trusted

# Audit a Go Evinse BOM enriched with Golem semantic properties
cdx-audit --bom bom.evinse.json --direct-bom-audit --categories golem

For Go projects, run evinse -l go --deep or evinse -l go --with-data-flow --golem-dataflow crypto before cdx-audit when you want Golem data-flow and crypto-flow properties such as cdx:golem:dataFlowSliceCount, cdx:golem:cryptoDataFlow, and cdx:golem:cryptoDataFlowCount to participate in review and prioritization.

Note: cdxgen supports reading both OCI Referrers and BuildKit in-toto attestations natively. When working with container images, you can directly pass the OCI image reference to tools like cdx-validate and cdx-verify to automatically fetch and evaluate attached SBOMs.

Note: --bom-audit automatically enables --include-formulation to collect CI/CD workflow data. For AI/ML scans, this also emits the discovered AI and agentic inventory in the formal CycloneDX formulation[] section. The formulation section may include sensitive data such as emails and environment details. Always review the generated SBOM before distribution.

Dry-run mode

--bom-audit works with --dry-run, but the two audit layers behave differently:

  • Formulation audit continues to run normally because it evaluates the already-generated BOM in memory.
  • Predictive dependency audit switches to planning mode. cdxgen still selects candidate npm/PyPI/Cargo targets, but it does not fetch registry metadata, clone upstream repositories, or generate child SBOMs.

The categories that work best in dry-run mode are the formulation-centric ones:

  • asar-archive
  • ai-agent
  • ai-bom (alias for ai-governance,ai-security,ai-performance,ai-agent,mcp-server)
  • ai-inventory (alias for ai-agent,mcp-server)
  • chrome-extension
  • ci-permission
  • container-risk
  • dependency-source
  • golem-security
  • golem-performance
  • golem-compliance
  • hbom-security
  • hbom-performance
  • hbom-compliance
  • host-topology
  • mcp-server
  • obom-runtime
  • vscode-extension

package-integrity is only partially covered in dry-run mode. Rules that can be evaluated from the current BOM still run, but predictive upstream analysis is intentionally skipped. asar-archive rules are mostly dry-run friendly because cdxgen can still read ASAR headers and file contents natively, recurse into nested archives, and evaluate Electron header-signing metadata in memory, but embedded npm install-script findings remain partial because temp extraction is still blocked.

Built-in BOM audit rules now declare an explicit dry-run-support tag with one of these values:

  • full — the rule is expected to evaluate normally in dry-run mode
  • partial — the rule can still match, but dry-run BOM generation may omit some supporting metadata
  • no — the rule depends on metadata that dry-run intentionally does not collect

When you run cdxgen --bom-audit --dry-run, the BOM audit summary reports how many of the active rules are tagged no and how many are tagged partial. If the summary reports any partial or no rules, treat the dry-run result as coverage guidance only and re-run without --dry-run before treating a clean result as complete.

How it works

The audit runs as a post-processing step after BOM generation:

  1. Load rules — Built-in rules from data/rules/ are loaded first. If --bom-audit-rules-dir is specified, user rules are merged in.
  2. Evaluate — Each rule's JSONata condition expression is evaluated against the full BOM. Matching components or workflows become findings.
  3. Report — Findings are printed to the console with severity icons and optionally embedded as CycloneDX annotations in the output BOM.
  4. Gate — In secure mode (CDXGEN_SECURE_MODE=true), findings at or above --bom-audit-fail-severity cause a non-zero exit code.
┌──────────────────────┐
│  createBom(path, opt)│
│   + postProcess()    │
└──────────┬───────────┘


┌──────────────────────┐
│   auditBom(bomJson)  │
│                      │
│  ┌────────────────┐  │
│  │  loadRules()   │  │  ← data/rules/*.yaml + user rules
│  └───────┬────────┘  │
│          │           │
│  ┌───────▼────────┐  │
│  │ evaluateRules() │  │  ← JSONata conditions against BOM
│  └───────┬────────┘  │
│          │           │
│  ┌───────▼────────┐  │
│  │ formatFindings  │  │  ← console output + CycloneDX annotations
│  └────────────────┘  │
└──────────────────────┘

CLI options

OptionTypeDefaultDescription
--bom-auditbooleanfalseEnable post-generation security audit
--bom-audit-rules-dirstringDirectory containing additional YAML rule files (merged with built-in rules)
--bom-audit-categoriesstringallComma-separated list of rule categories to enable. Unknown categories are rejected, and aliases such as ai-inventory and hbom expand to their built-in category sets.
--bom-audit-min-severitystringlowMinimum severity to report: low, medium, high
--bom-audit-fail-severitystringhighSeverity level at or above which findings cause secure mode failure (e.g., medium fails on medium, high, and critical)
--bom-audit-scopestringallPredictive dependency audit target scope: all or required
--bom-audit-max-targetsnumberautoPredictive dependency audit cap. By default cdxgen prioritizes direct runtime and required targets first and expands to at least 50 targets
--bom-audit-include-trustedbooleanfalseInclude predictive audit targets that already carry trusted publishing metadata
--bom-audit-only-trustedbooleanfalseRestrict predictive audit targets to trusted-publishing-backed packages only

Predictive dependency target selection

When --bom-audit is enabled, cdxgen narrows predictive dependency audit targets before cloning upstream repositories:

  • packages with trusted publishing metadata (cdx:cargo:trustedPublishing=true, cdx:npm:trustedPublishing=true, or cdx:pypi:trustedPublishing=true) are skipped by default
  • built-in well-known purl prefixes such as pkg:npm/%40babel, pkg:npm/npm, and pkg:npm/%40types are skipped by default
  • --bom-audit-scope required keeps only dependencies with CycloneDX scope=required (missing scope is treated as required)
  • unless you override it, cdxgen caps the predictive dependency audit to max(50, required-target-count) and prioritizes direct runtime and required targets first
  • explicit scope=required and richer evidence.occurrences act as prioritization indicators when cdxgen trims the queue
  • Cargo runtime-facing crates stay ahead of build-only workspace helper crates when the predictive queue is truncated

Use the trusted-publishing switches to override the default:

  • --bom-audit-include-trusted includes both trusted-publishing-backed and non-trusted packages
  • --bom-audit-only-trusted scans only trusted-publishing-backed packages

Passing both trusted switches together is invalid and causes cdxgen to exit with an error.

HBOM-only runs are intentionally different: when projectType is hbom/hardware (or you use the dedicated hbom command), cdxgen skips the predictive dependency audit entirely and defaults the audit categories to hbom-security,hbom-performance,hbom-compliance.

When you also pass --include-runtime, cdxgen keeps the same predictive-audit skip behavior but extends the default categories to hbom-security,hbom-performance,hbom-compliance,host-topology.

Built-in rule categories

ci-permission — CI/CD Permission Security

Rules that evaluate GitHub Actions, GitLab CI, and other CI/CD workflow data for privilege and supply-chain risks.

RuleSeverityDescription
CI-001highUnpinned GitHub Action in a workflow with write permissions
CI-002highOIDC token (id-token: write) granted to non-official action
CI-003mediumGitHub Action pinned to a mutable tag instead of SHA
CI-004mediumWorkflow uses pull_request_target trigger
CI-021mediumHeuristic review: high-risk trigger, no explicit permissions block, and sensitive operations
CI-018highFork-reachable or privileged workflow dispatches downstream workflows/events
CI-019criticalDispatch chain combines explicit fork context with sensitive credentials
CI-009mediumWorkflow file contains hidden Unicode characters
CI-010mediumnpm/PyPI publish step uses legacy token-based publishing

dependency-source — Dependency Source Integrity

Rules that check package manager data for non-registry, local, or mutable dependency sources.

RuleSeverityDescription
PKG-001highnpm package with install script from non-registry source
PKG-002highGo module uses local replace directive
PKG-003highSwift package uses local checkout path
PKG-004highNix flake missing reproducibility metadata (revision or nar_hash)
PKG-005mediumRuby gem tracks mutable branch without commit pin
PKG-006mediumPython package from non-default PyPI registry
PKG-007highCargo dependency tracks mutable git source without immutable pin
PKG-008highCargo dependency uses local path source

package-integrity — Package Integrity and Lifecycle

Rules that detect deprecated, yanked, tampered, or suspicious packages.

RuleSeverityDescription
INT-001mediumnpm package has install-time execution hooks
INT-002highnpm package name or version mismatch (possible dependency confusion)
INT-003mediumDeprecated Go module
INT-004highYanked Ruby gem
INT-005lowDeprecated npm package
INT-006mediumDart pub uses non-default registry
INT-007lowMaven package contains shaded/relocated classes
INT-008mediumREADME file contains hidden Unicode characters
INT-009criticalnpm lifecycle hook contains obfuscated or encoded install-time execution
INT-010highCargo crate has been yanked from crates.io
INT-011mediumRust project uses Cargo build.rs or native build helpers
INT-012mediumRust native build uses mutable Cargo toolchain setup action
INT-013mediumRust native build is exercised by Cargo workflow build/test/package steps

Advanced predictive heuristics

Beyond the YAML rule matches above, the current rollout also adds a small number of deliberately high-signal source heuristics for cdx-audit scans:

  • GitHub Actions lateral movement: downstream workflow_dispatch / repository_dispatch chains launched from fork-reachable or privileged workflows
  • npm install-time concealment: base64-decoding or otherwise obfuscated lifecycle hooks, including referenced JS files analyzed through the Babel-based source analyzer
  • PyPI packaging surfaces: shallow heuristics for suspicious logic in setup.py and package __init__.py
  • Cargo registry and native build signals: yanked crates, mutable git/path dependencies, build-only workspace helpers, and Cargo build.rs/native-helper build surfaces
  • Cargo workflow tie-ins: mutable Cargo setup actions plus Cargo build/test/package/publish workflow steps correlated with native build surfaces

The Python detections are intentionally conservative phase-1 heuristics. They are meant to catch obviously suspicious packaging behavior today while a deeper Python static-analysis path is developed separately.

golem-security, golem-performance, golem-compliance — Go Evinse semantic evidence review

Rules that evaluate cdx:golem:* properties emitted by evinse -l go when the golem helper is available. These rules are intended to run after the base Go SBOM has been enriched into bom.evinse.json.

cdxgen -t go -o bom.json /absolute/path/to/go/project
evinse -i bom.json -o bom.evinse.json -l go /absolute/path/to/go/project
cdx-audit --bom bom.evinse.json --direct-bom-audit --categories golem

golem is an alias for golem-security,golem-performance,golem-compliance.

RuleCategorySeverityDescription
GOLEM-SEC-001golem-securitymediumRuntime Go dependency has a high-severity semantic security signal
GOLEM-SEC-002golem-securitylowGo crypto material flows into a crypto sink
GOLEM-SEC-003golem-securitylowGo component has a cryptographic finding
GOLEM-SEC-004golem-securitylowGo module uses a local replacement in analyzed source
GOLEM-PERF-001golem-performancelowGo project crosses a native code boundary
GOLEM-PERF-002golem-performancelowGo project relies on generated or embedded build inputs
GOLEM-PERF-003golem-performancelowGo data-flow evidence was truncated or sanitized
GOLEM-COMP-001golem-compliancelowGo module appears private or workspace-local
GOLEM-COMP-002golem-compliancemediumVendored Go module lacks license-file evidence
GOLEM-COMP-003golem-compliancelowGo module graph uses exclude directives

These rules use properties such as cdx:golem:securitySignalSeverity, cdx:golem:usageScopes, cdx:golem:cryptoDataFlow, cdx:golem:cryptoFinding, cdx:golem:localReplacement, cdx:golem:privateModuleCandidate, cdx:golem:vendored, cdx:golem:licenseFileCount, cdx:golem:nativeArtifactCount, cdx:golem:goGenerateCount, cdx:golem:goEmbedCount, cdx:golem:dataFlowTruncated, and cdx:golem:goModExcludeCount.

Typical reviewer actions:

  • inspect .occurrences and .callstack for dependencies with security signals before deciding whether the signal is reachable and relevant
  • review cdx:golem:cryptoDataFlow* and cdx:golem:cryptoFinding* evidence for key provenance, algorithm safety, TLS settings, and secret-handling risks
  • remove local replacements from release builds or document why a local or vendored source is part of the release baseline
  • verify internal provenance, access-control, license, and vulnerability intake for private module candidates
  • review native, generated, and embedded asset surfaces for reproducibility, license coverage, and cross-platform build behavior
  • treat truncated data-flow evidence as coverage-limited and rerun with narrower patterns or larger limits before relying on a clean result
  • document why each go.mod exclude directive exists and verify the selected module versions are safe and reproducible

asar-archive — Electron ASAR release artifact review

Rules that evaluate packaged Electron .asar artifacts for dynamic execution, capability overlap, integrity mismatches, nested archive evidence, and Electron signing metadata.

RuleSeverityDescription
ASAR-001highArchived JavaScript with eval or dynamic loading
ASAR-002highArchived JavaScript with network plus file or hardware access
ASAR-003highDeclared ASAR integrity mismatch
ASAR-004highEmbedded npm package with install-time scripts inside ASAR
ASAR-005highElectron ASAR signing metadata failed verification

Notes for reviewers:

  • nested archives are surfaced as chained identities such as outer.asar#/nested/core.asar#/src/main.js
  • archive-internal paths are normalized to forward slashes, even when the outer archive lives on Windows
  • cdx:asar:signingScope=header-only means Electron signing evidence verifies the ASAR header hash scope, not all packed payload bytes

host-topology — Strict HBOM + OBOM host-view correlation

Rules that only apply when a host BOM contains both hardware inventory and runtime inventory linked by explicit identifiers.

RuleSeverityDescription
HMX-001mediumA wired interface with live runtime address evidence is negotiated at degraded speed/duplex
HMX-002highA wireless interface has live runtime address evidence while link security is weak
HMX-003mediumA merged host view contains zero strict HBOM ↔ OBOM topology links
HMX-004highA mounted storage device with explicit runtime evidence is reporting degraded health
HMX-005highAn explicit HBOM Secure Boot trust anchor matches revoked runtime certificate evidence

These rules are intentionally conservative. They rely on derived cdx:hostview:* properties produced only from exact, evidence-backed joins such as interface-name equality, driver-module equality, storage device-node or mount-path equality, logical-drive identifiers, and explicit Secure Boot certificate identifiers. They do not infer links from fuzzy naming similarity.

mcp-server — MCP server exposure and trust posture

Rules that evaluate MCP server inventory emitted from JavaScript/TypeScript source analysis.

RuleSeverityDescription
MCP-001criticalStreamable HTTP MCP server exposes tools without authentication
MCP-002highStreamable HTTP MCP server endpoint is reachable without authentication
MCP-003mediumNetwork-exposed MCP server relies on a non-official SDK or wrapper
MCP-004highConfigured MCP HTTP endpoint lacks any discovered auth posture
MCP-005criticalMCP configuration exposes inline credentials
MCP-006highMCP configuration suggests confused-deputy risk
MCP-007highMCP configuration forwards or passes through bearer-like credentials
MCP-008mediumBuild/post-build SBOM includes an MCP configuration file

ai-agent — AI agent instruction and MCP governance

Rules that evaluate AI agent instruction files, skill files, and inferred MCP surfaces referenced only from those files.

RuleSeverityDescription
AGT-001mediumAI agent instruction or skill file contains hidden Unicode characters
AGT-002highAI agent instructions reference a public MCP endpoint without auth hints
AGT-003mediumAI agent instructions reference MCP surfaces not otherwise declared in the BOM
AGT-004highAI agent instructions reference tunneled or reverse-proxied MCP exposure
AGT-005mediumAI agent instructions reference non-official MCP wrappers or packages
AGT-006criticalAI agent instruction or skill file contains inline credential patterns
AGT-007mediumBuild/post-build SBOM includes an AI instruction or skill file

ai-inventory — Umbrella alias for AI inventory review

Use ai-inventory with --bom-audit-categories when you want one switch that enables both ai-agent and mcp-server findings for AI instruction files, skill files, MCP configs, and discovered MCP services.

ai-bom — Preferred umbrella alias for AI-BOM review

Use ai-bom when you want one switch that enables:

  • ai-governance
  • ai-security
  • ai-performance
  • ai-agent
  • mcp-server

This is the recommended category for AI-heavy repositories because it combines prompt/config governance, AI endpoint hygiene, local-model sizing signals, AI instruction review, and MCP exposure checks in one pass.

ai-governance — Prompt/config and model-governance review

RuleSeverityDescription
AIG-001mediumBuild/post-build SBOM includes a prompt or model-routing file
AIG-002mediumAI inference service is used without an explicit model ID

ai-security — AI endpoint transport review

RuleSeverityDescription
AIS-001highAI inference service uses insecure remote HTTP transport

ai-performance — Local-model capacity and sizing review

RuleSeverityDescription
AIP-001mediumLocal AI model advertises a very large context window
AIP-002mediumLarge local AI model lacks quantization metadata

Standards mapping

The AI, MCP, and AI-agent rule sets now carry standards metadata that can be surfaced in audit annotations and downstream compliance workflows. The current mappings focus on:

  • OWASP AI Top 10 for plugin, agency, and supply-chain exposure themes
  • OWASP Top 10 for Agentic Applications (2026) for agent goal, tool, privilege, communication, and agentic supply-chain exposure themes
  • EU AI Act for documentation, transparency, oversight, and robustness review themes
  • EU Cyber Resilience Act for software-component documentation, secure defaults, credential handling, and network exposure review themes
  • NIST AI RMF for governance, mapping, and risk-management review flows
  • NIST SSDF for provenance, interface hardening, and automation/build instruction review

Typical reviewer use:

  • acceptable — localhost-only, official SDK or config, explicit auth posture, no inline credentials
  • needs review — public endpoint references, non-official wrappers, tunneled exposure, or undeclared MCP/config references
  • block — inline credentials, unauthenticated public MCP endpoints, or confused-deputy / token-passthrough indicators

Treat these mappings as reviewer guidance rather than a full certification crosswalk.

obom-runtime — Operational Runtime and Host Posture

Rules that evaluate OBOM runtime components from osquery-derived host telemetry for persistence, endpoint control gaps, suspicious startup/runtime behavior, Linux GTFOBins-enriched activity, hardening drift, and Windows LOLBAS / ATT&CK-aligned abuse patterns.

Recent additions broaden the Linux and trust-aware host coverage:

  • live Linux GTFOBins enrichment is applied to osquery runtime rows such as sudo executions, privilege transitions, elevated processes, and privileged listeners
  • Linux hardening checks review dedicated sysctl_hardening and mount_hardening query-pack entries inspired by Lynis and CIS baselines
  • trustinspector-backed properties such as cdx:windows:authenticode:*, cdx:windows:wdac:*, and cdx:darwin:notarization:* are used directly in the built-in rules
RuleSeverityDescription
OBOM-LNX-001highLinux systemd unit sourced from temporary path
OBOM-LNX-002highLinux sudoers broad privilege rule
OBOM-LNX-003mediumRoot authorized_keys entry without restrictions
OBOM-LNX-004highLinux shell history contains suspicious download-execute pattern
OBOM-LNX-005criticalDocker API exposed over unauthenticated TCP port
OBOM-LNX-006highPrivileged Linux listener exposed on a non-local interface
OBOM-LNX-007highAdministrative Linux surface running with elevated privileges
OBOM-LNX-008highInteractive sudo chain touched sensitive administrative binary
OBOM-LNX-009highUnexpected Linux privilege transition for non-allowlisted executable
OBOM-LNX-010criticalElevated Linux process launched from user-writable or unusual path
OBOM-LNX-011mediumInteractive shell parent spawned privileged Linux execution
OBOM-LNX-014criticalLinux reverse shell behavior detected in live process telemetry
OBOM-LNX-015highLinux process uses LD_PRELOAD from writable or temporary path
OBOM-LNX-016highLinux cron entry fetches remote content or runs from writable path
OBOM-LNX-017mediumLinux sysctl posture diverges from common hardening baseline
OBOM-LNX-018highLinux temporary mount is missing key hardening flags
OBOM-LNX-019highLive Linux runtime artifact matches GTFOBins execution helper
OBOM-WIN-001highWindows drive without BitLocker protection
OBOM-WIN-002highWindows Security Center unhealthy state
OBOM-WIN-003criticalWindows Run key references temporary/script execution path
OBOM-WIN-004highHidden scheduled task uses suspicious execution path
OBOM-WIN-005criticalAuto-start Windows service points to user-writable path
OBOM-WIN-006highWindows persistence surface references LOLBAS execution helper
OBOM-WIN-007criticalWindows WMI or AppCompat persistence uses LOLBAS
OBOM-WIN-008highWindows startup or process activity uses network-capable LOLBAS
OBOM-WIN-009criticalNetwork-facing Windows listener is a LOLBAS execution helper
OBOM-WIN-010criticalWindows persistence artifact uses LOLBAS with UAC-bypass context
OBOM-WIN-011highWindows Public profile inbound firewall allow rule
OBOM-WIN-012criticalWindows startup or listener binary has invalid Authenticode status
OBOM-WIN-013highWindows host has no active WDAC policies
OBOM-MAC-001highmacOS firewall disabled or stealth mode off
OBOM-MAC-002criticalmacOS launchd item from user-writable temporary path
OBOM-MAC-003mediummacOS firewall exception for binary in untrusted user path
OBOM-MAC-004mediummacOS launchd override disables Apple-managed service
OBOM-MAC-005highmacOS Gatekeeper enforcement is disabled or weakened
OBOM-MAC-006mediummacOS running app launches from Downloads, Desktop, or temp path
OBOM-MAC-007highmacOS startup or application artifact failed notarization assessment

hbom-security, hbom-performance, hbom-compliance — Hardware inventory review

Rules that evaluate CycloneDX HBOMs generated by cdxgen -t hbom (or the dedicated hbom command output when later passed to cdx-audit) for hardware security posture, performance degradation signals, and governance completeness.

When you run cdxgen -t hbom --bom-audit without specifying categories, cdxgen automatically enables:

  • hbom-security
  • hbom-performance
  • hbom-compliance

You can also use the alias hbom with --bom-audit-categories to enable the full HBOM review pack in one switch.

hbom-security — Hardware security posture

RuleSeverityDescription
HBS-001highStorage component is explicitly unencrypted
HBS-002highConnected wireless adapter uses weak or missing link security
HBS-003highRemovable storage is attached without encryption or lock proof
HBS-004mediumHBOM exposes raw hardware identifiers
HBS-005highExternal expansion bus reports permissive security posture
HBS-006mediumHBOM exposes raw cellular or subscriber identifiers

Typical reviewer actions:

  • enable or verify disk / volume encryption before distributing the host
  • remove or re-baseline removable media that is attached without lock or encryption assurance
  • move wireless links to WPA2/WPA3-class protections and confirm SSID policy
  • share redacted HBOMs externally unless raw identifiers are explicitly required

hbom-performance — Hardware capacity and degradation signals

RuleSeverityDescription
HBP-001mediumStorage volume has low free capacity headroom
HBP-002highStorage health is degraded or wear is near exhaustion
HBP-003highThermal zone reports sustained high temperature
HBP-004mediumBattery health is degraded
HBP-005mediumActive wired link is operating below expected duplex/bandwidth
HBP-006highInstalled memory is only partially online
HBP-007mediumBattery design capacity has materially degraded
HBP-008mediumUSB device requires more current than the bus reports available
HBP-009mediumCellular modem reports weak signal quality

Typical reviewer actions:

  • free storage or relocate logs/caches before patching, indexing, or builds begin to fail
  • replace worn SSDs or failing storage before latency-sensitive workloads degrade further
  • inspect cooling, dust, fan policy, and workload placement when thermal zones stay hot
  • replace batteries or adjust charging policy for mobile devices with poor health
  • investigate link negotiation, cabling, switch policy, and memory-online drift before blaming application performance alone

hbom-compliance — Governance and evidence completeness

RuleSeverityDescription
HBC-001mediumHBOM inventory lacks firmware or board provenance
HBC-002mediumManaged asset identity is incomplete
HBC-003mediumHBOM collector evidence is incomplete
HBC-004mediumStorage inventory lacks encryption posture evidence
HBC-005mediumHBOM uses non-redacted identifier policy
HBC-006mediumHBOM collector is missing optional enrichment commands
HBC-007mediumHBOM collector hit permission-denied enrichments
HBC-008mediumHBOM collector is missing firmware-management enrichment
HBC-009mediumHBOM board and BIOS provenance was blocked by permissions
HBC-010mediumHBOM display and DRM evidence is incomplete

These rules are mapped where practical to common governance references such as:

  • NIST SP 800-53 (CM-8, SC-28, SI-7)
  • CIS Controls v8 asset inventory, removable-media, and encryption expectations
  • ISO/IEC 27001 inventory and cryptography controls

Typical reviewer actions:

  • confirm that CMDB / asset-management fields can reconcile the HBOM to the physical device
  • preserve collector command evidence so the inventory is reproducible during audit or incident review
  • capture explicit storage encryption posture for governed devices
  • prefer redacted identifier policy for broadly shared BOMs
  • use hbom diagnostics or the derived cdx:hbom:analysis:* summary properties to identify missing host packages before accepting a partial Linux HBOM
  • rerun with --privileged only when the diagnostic evidence shows permission-denied enrichments that are worth collecting and your target environment allows non-interactive sudo
  • install fwupdmgr, edid-decode, or other reported native helpers when you need the richer firmware-management or display evidence introduced by newer HBOM collectors
  • use cdxi pivots such as .hbomdiagnostics, .hbomfirmware, .hbombuses, and .hbompower when you want to inspect the exact hardware surfaces behind the findings

rootfs-hardening — Offline host and golden-image hardening review

Rules that evaluate reconstructed root filesystems, mounted images, and other offline host snapshots for repository trust, privileged helpers, stale trust anchors, and suspicious service definitions.

Use this category when you want image-baseline checks that do not depend on live osquery collection.

Generated image and rootfs BOMs also carry cdx:container:unpackagedExecutableCount and cdx:container:unpackagedSharedLibraryCount metadata properties, plus a metadata annotation sentence summarizing the same counts. These counts track executable and shared-library file components discovered from collectExecutables() and collectSharedLibs() after OS package ownership has been excluded.

RuleSeverityDescription
RFS-001highEnabled OS repository uses plaintext HTTP transport
RFS-002criticalYUM repository has package signature checks disabled
RFS-003highOffline trust anchor is marked expired
RFS-004criticalOffline image retains setuid GTFOBins execution helper
RFS-005criticalOffline service executes from writable or temporary path
RFS-006highOffline service pre-start step fetches or shells remote content

container-risk — Container Escape, Privilege, and Post-Exploit Tooling

Rules that evaluate collected container executables against GTFOBins-derived enrichment plus MITRE ATT&CK for Containers, Peirates/CDK/DEEPCE playbook knowledge, and Docker seccomp guidance to highlight container breakout helpers, privileged execution primitives, offensive toolkits, and seccomp-sensitive escape helpers.

When a finding or count summary needs manual follow-up, import the BOM into cdxi and pivot with .unpackagedbins or .unpackagedlibs to inspect only the native file components that were not matched to OS package ownership.

RuleSeverityDescription
CTR-001criticalContainer image ships setuid/setgid GTFOBins execution primitive
CTR-002criticalContainer image includes privileged container-escape helper
CTR-003highContainer image includes privileged GTFOBins library-load primitive
CTR-004highContainer image retains privileged GTFOBins exfiltration primitive
CTR-005mediumContainer image includes mutable-path remote-execution helper
CTR-006highContainer image ships dedicated offensive container toolkit
CTR-007mediumContainer image includes seccomp-sensitive namespace escape helper
CTR-008mediumContainer dependency relies on the mutable 'latest' tag

vscode-extension — VS Code Extension Security

Rules that evaluate VS Code extension metadata for install-time execution, always-on activation, workspace trust posture, and privileged capabilities.

RuleSeverityDescription
VSC-001criticalVS Code extension has install-time lifecycle scripts
VSC-002highAlways-on extension (* activation) exposes terminal access
VSC-003highExtension runs in untrusted workspaces with filesystem access
VSC-006highExtension contributes debugger/authentication provider capabilities
VSC-007highWorkspace-context extension executes code

chrome-extension — Chromium Browser Extension Security

Rules that evaluate Chrome/Chromium/Edge/Brave extension metadata for broad site access, request interception, early script injection, autofill, and capability-derived risk posture (file/device/code-injection/fingerprinting).

RuleSeverityDescription
CHE-001highExtension has broad host access (<all_urls> or wildcard host permissions)
CHE-002criticalExtension can intercept and block web requests (webRequest + webRequestBlocking)
CHE-003highExtension injects content scripts at document_start with broad host access
CHE-004mediumAutofill-capable extension has broad host permissions
CHE-005highExtension combines broad host scope with file/device/bluetooth capabilities
CHE-006criticalExtension has code-injection capability with broad host scope
CHE-007highExtension has fingerprinting capability indicators with broad host scope
CHE-008highAI-assistant extension has code-injection capability on OpenAI/Claude/Copilot domains

Writing custom rules

Rules are YAML files placed in a directory and loaded via --bom-audit-rules-dir. Each file can contain a single rule object or a YAML array of rules.

Rule schema

- id: CUSTOM-001 # Required: unique identifier
  name: "Human-readable name" # Optional: display name (defaults to id)
  description: "Long description" # Optional: detailed explanation
  severity: high # Required: critical, high, medium, or low
  category: my-category # Required: grouping for --bom-audit-categories
  condition: | # Required: JSONata expression returning matches
    components[
      $prop($, 'cdx:npm:hasInstallScript') = 'true'
    ]
  location: | # Optional: JSONata expression for finding location
    { "bomRef": $."bom-ref", "purl": purl }
  message: "Template with {{ name }}" # Required: message template with {{ expr }} interpolation
  mitigation: "How to fix this" # Optional: remediation guidance
  attack: # Optional: MITRE ATT&CK metadata propagated to findings / SARIF / annotations
    tactics: [TA0001, TA0004]
    techniques: [T1195.001]
  evidence: | # Optional: JSONata expression for evidence data
    { "key": $prop($, 'cdx:npm:risky_scripts') }

Available JSONata helpers

The rule engine registers custom functions for working with CycloneDX properties:

FunctionDescriptionExample
$prop(obj, name)Extract a property value by name$prop($, 'cdx:npm:hasInstallScript')
$nullSafeProp(obj, name)Extract a property value but return "" when it is missing; useful for string matching$nullSafeProp($, 'cdx:github:workflow:triggers') ~> $contains('pull_request')
$hasProp(obj, name)Check if property exists$hasProp($, 'cdx:npm:risky_scripts')
$hasProp(obj, name, value)Check if property equals value$hasProp($, 'cdx:npm:isLink', 'true')
$p(obj, name)Short alias for $prop$p($, 'cdx:go:local_dir')
$hasP(obj, name, value)Short alias for $hasProp$hasP($, 'cdx:gem:yanked', 'true')
$propBool(obj, name)Extracts property and normalizes to JS boolean ( true / false / null ). Case-insensitive and null-safe.$propBool($, 'cdx:github:workflow:hasWritePermissions') = true
$propList(obj, name)Splits comma-separated property strings into a trimmed JSONata array. Returns [] if missing.$propList($, 'cdx:github:workflow:triggers')
$listContains(val, target)Safely checks if val (array or string) contains target. Works with both $propList output and raw strings.$listContains($propList($, 'cdx:vscode-extension:contributes'), 'terminal-access')
$safeStr(val)Guarantees a trimmed string return. Converts null/undefined to "" . Ideal for regex matching and template interpolation.$match($safeStr($prop($, 'cdx:npm:versionSpecifiers')), /^\^/)
$startsWith(str, prefix)String prefix check$startsWith(purl, 'pkg:nix/')
$endsWith(str, suffix)String suffix check$endsWith(name, '-beta')
$arrayContains(arr, value)Check array membership$arrayContains(tags, 'deprecated')
$auditComponents(bom)Return a deduplicated array of top-level BOM components plus any formulation[].components$auditComponents($)[$prop($, 'cdx:github:action:isShaPinned') = 'false']
$auditServices(bom)Return a deduplicated array of top-level BOM services$auditServices($)[$contains($safeStr($prop($, 'cdx:service:ExecStart')), '/tmp/')]
$auditWorkflows(bom)Return a deduplicated array of all formulation[].workflows entries$auditWorkflows($)[$prop($, 'cdx:github:workflow:hasHighRiskTrigger') = 'true']
$formulationComponents(bom)Return only formulation[].components$formulationComponents($)[$prop($, 'cdx:github:step:type') = 'run']

Message templates

The message field supports {{ expression }} syntax for dynamic content. The template context includes the matched component/item plus the full BOM:

message: "Package '{{ name }}@{{ version }}' from registry {{ $prop($, 'cdx:pypi:registry') }}"

Condition patterns

Match components by property value

condition: |
  components[
    $prop($, 'cdx:npm:hasInstallScript') = 'true'
  ]

Match components by property existence

condition: |
  components[
    $hasProp($, 'cdx:go:local_dir')
  ]

Combine multiple conditions

condition: |
  $auditComponents($)[
    $prop($, 'cdx:github:action:isShaPinned') = 'false'
    and (
      $prop($, 'cdx:github:workflow:hasWritePermissions') = 'true'
      or $prop($, 'cdx:github:job:hasWritePermissions') = 'true'
    )
  ]

Match workflow data

condition: |
  $auditWorkflows($)[
    $nullSafeProp($, 'cdx:github:workflow:triggers') ~> $contains('pull_request_target')
  ]

ATT&CK metadata in outputs

When a rule defines an attack: block, cdxgen carries that metadata through to:

  • BOM-audit finding objects as attackTactics / attackTechniques
  • CycloneDX annotations as cdx:audit:attack:tactics / cdx:audit:attack:techniques
  • SARIF rule/result properties and SARIF tags like ATT&CK:TA0004

This keeps the rule schema lightweight while making ATT&CK-aligned detections available to downstream reporting and triage pipelines.

Use purl-based filtering

condition: |
  components[
    $startsWith(purl, 'pkg:nix/')
    and $prop($, 'cdx:nix:revision') = null
  ]

Output formats

Console output

Findings are printed with severity-coded icons:

Formulation audit: 3 finding(s)

⛔ [CUSTOM-001] Critical finding message
🔴 [CI-001] Unpinned GitHub Action 'actions/setup-node@v3' in workflow with write permissions
🟡 [CI-003] GitHub Action 'actions/checkout@v3' pinned to mutable tag (not SHA)
🔵 [INT-005] npm package 'leftpad@0.0.1' is deprecated

CycloneDX annotations

When the BOM spec version is ≥ 1.4, findings are embedded as annotations:

{
  "annotations": [
    {
      "subjects": ["urn:uuid:..."],
      "annotator": {
        "component": { "name": "cdxgen", "version": "..." }
      },
      "timestamp": "2025-01-01T00:00:00.000Z",
      "text": "Unpinned GitHub Action 'actions/setup-node@v3' in workflow with write permissions",
      "properties": [
        { "name": "cdx:audit:ruleId", "value": "CI-001" },
        { "name": "cdx:audit:severity", "value": "high" },
        { "name": "cdx:audit:category", "value": "ci-permission" },
        { "name": "cdx:audit:mitigation", "value": "Pin action to full SHA..." }
      ]
    }
  ]
}

Audit and validation annotations now render their properties as markdown tables instead of JSON blobs, which improves readability in Dependency-Track, GitHub, and other CycloneDX annotation consumers.

Environment variables

VariableDescription
CDXGEN_DEBUG_MODE=debugShow verbose audit logging
CDXGEN_SECURE_MODE=trueEnable secure mode (audit failures cause non-zero exit)

Relationship to custom properties

The audit rules are powered by the cdx: Custom Properties that cdxgen adds to BOM components, workflows, and metadata. See that document for the full inventory of available properties and their value semantics.

Frequently asked questions

Q: Does --bom-audit slow down BOM generation?

--bom-audit now has two layers:

  1. the original in-memory BOM audit, which evaluates JSONata expressions against the generated BOM
  2. a predictive dependency audit for npm and PyPI components, which may resolve source repositories and generate child SBOMs

For projects without npm/PyPI dependencies, the overhead is usually minimal. For npm/PyPI-heavy projects, the predictive pass can add noticeable time because it may query registries and inspect upstream source repositories.

To keep large projects responsive, the predictive pass now prints a preflight hint for larger target sets, skips trusted-publishing-backed packages by default, and prioritizes required dependencies before optional ones when a target cap applies.

Q: What are the limitations of --bom-audit --dry-run?

Dry-run BOM audit is intentionally conservative:

  1. formulation findings are complete only to the extent that the generated BOM captured the relevant metadata
  2. predictive dependency audit is limited to candidate-target planning
  3. registry metadata enrichment, upstream repository cloning, and child SBOM generation are skipped
  4. categories that depend heavily on predictive upstream inspection—especially parts of package-integrity—will produce fewer findings than a normal run

Q: Can I disable specific built-in rules?

Use --bom-audit-categories to restrict which categories run. Individual rule disabling is planned for a future release.

Q: How does provenance affect the predictive audit score?

Registry-visible provenance such as trusted publishing, provenance URLs, and verified uploaders is treated as a score reducer and confidence input. Missing provenance is only used as a weak contextual detector and is never intended to produce a high-severity finding on its own.

Q: How do I use this in CI/CD pipelines?

# GitHub Actions example
- name: Generate SBOM with audit
  run: |
    cdxgen -o bom.json --bom-audit --bom-audit-fail-severity high
  env:
    CDXGEN_SECURE_MODE: "true"

In secure mode, any finding at or above --bom-audit-fail-severity causes a non-zero exit code, failing the pipeline step.