Skip to content

cdxgen/cdx-hbom

Repository files navigation

cdx-hbom

cdx-hbom is a small, dependency-free Hardware Bill of Materials (HBOM) collector for CycloneDX BOM tools.

It currently supports following OS hosts:

  • darwin/arm64 (Apple Silicon Macs)
  • linux/amd64
  • linux/arm64

Install

npm

npm install @cdxgen/cdx-hbom

JSR

npx jsr add @cdxgen/cdx-hbom

CLI

Generate a hardware inventory for the current host:

npx @cdxgen/cdx-hbom --pretty > host-hbom.json

Common options:

  • --pretty pretty-print the JSON output
  • --dry-run block command execution and trace planned collection activity
  • --platform <value> override platform detection
  • --arch <value> override architecture detection
  • --sensitive include raw identifiers instead of redacted defaults
  • --no-command-enrichment disable optional command-based enrichment on Linux
  • --privileged enable privileged Linux enrichment and explicit non-interactive sudo -n retries for documented permission-sensitive commands that opt in (currently drm_info)
  • --plist-enrichment enable additional Darwin plist-based enrichment
  • --strict fail instead of returning partial results when enrichment fails
  • --timeout <ms> set per-command timeout

Examples:

npx @cdxgen/cdx-hbom --pretty
npx @cdxgen/cdx-hbom --privileged --pretty > linux-hbom.json
npx @cdxgen/cdx-hbom --plist-enrichment --pretty > mac-hbom.json

Library usage

import {
  collectHardware,
  createCollectorTrace,
  buildHardwareFromSources,
  getCollectorTrace,
  getCommandPlan,
} from "@cdxgen/cdx-hbom";

const trace = createCollectorTrace();

const bom = await collectHardware({
  dryRun: true,
  includePlistEnrichment: true,
  trace,
});

const collectedTrace = getCollectorTrace(bom) ?? trace;
console.log(collectedTrace.activities);

const plan = getCommandPlan({ platform: "linux", architecture: "amd64" });

// Some plan entries are templates; their final arguments are resolved per
// device or interface at runtime when live collection expands the plan.

const rebuilt = buildHardwareFromSources({
  platform: "linux",
  architecture: "amd64",
  sources: {
    osRelease: { NAME: "Ubuntu", VERSION_ID: "24.04" },
    cpuInfo: [{ processor: "0", "model name": "AMD Ryzen 7" }],
  },
});

Reading command diagnostics from the library

cdx-hbom keeps JSON output on the BOM itself and records optional command issues in the attached collector trace and BOM evidence properties.

import {
  collectHardware,
  createCollectorTrace,
  getCollectorTrace,
} from "@cdxgen/cdx-hbom";

const trace = createCollectorTrace();

const bom = await collectHardware({
  platform: "linux",
  architecture: "amd64",
  includeCommandEnrichment: true,
  includePrivilegedEnrichment: true,
  allowPartial: true,
  trace,
});

const collectedTrace = getCollectorTrace(bom) ?? trace;
const commandDiagnostics = collectedTrace.activities.filter(
  (entry) =>
    entry.kind === "command-diagnostic" || entry.kind === "command-warning",
);

for (const entry of commandDiagnostics) {
  if (entry.issue === "missing-command") {
    console.error(
      `Install hint for ${entry.command}: ${entry.hint ?? "see package docs"}`,
    );
  }

  if (entry.issue === "permission-denied") {
    console.error(
      `Privilege hint for ${entry.command}: ${entry.hint ?? "retry with --privileged"}`,
    );
  }
}

You can also read serialized command diagnostics from the BOM root by inspecting cdx:hbom:evidence:commandDiagnostic* properties.

Native enrichment currently covered

cdx-hbom uses a fixed command registry and array-based process spawning, but upstream wrappers and integrators are responsible for any stricter command allowlisting, PATH hardening, or execution policy controls around the collector process.

Dry-run and trace support

  • dryRun: true blocks command execution inside cdx-hbom itself instead of relying on a caller-side fallback.
  • getCommandPlan() exposes the static command registry, including template entries whose concrete arguments are resolved per device or interface at runtime.
  • Successful file reads and directory discovery, plus completed/blocked/failed command attempts, are recorded in the collector trace.
  • Pass trace: createCollectorTrace() to collect activity into a caller-owned ledger, or read it later via getCollectorTrace(bom).
  • The attached trace is non-enumerable, so JSON.stringify(bom) still emits a normal CycloneDX document.

Linux

  • /proc and /sys baseline discovery
  • CPU, memory, storage, PCI, USB, DRM display, audio, MMC/SDIO, and network inventory
  • hwmon, thermal zones, TPM, and NVMe controller enrichment
  • optional command enrichment via lscpu, lsblk, ip, lsmem, hostnamectl, lspci, lsusb, ethtool, cpupower, drm_info, upower, fwupdmgr, boltctl, mmcli, and edid-decode
  • command diagnostics for missing utilities, partial support, and permission-sensitive enrichments

If you want to improve Linux enrichment coverage by installing the optional host tools, see linux-troubleshooting.md.

Darwin arm64

  • system_profiler hardware, storage, display, Wi-Fi, USB, audio, camera, Bluetooth, Thunderbolt, and power data
  • networksetup hardware-port mapping
  • live ifconfig network-interface enrichment
  • optional plist enrichment via diskutil, diskutil apfs list -plist, and ioreg

Development

npm test

License

MIT

About

Hardware Bill-of-Materials (HBOM) library.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Contributors