@cdxgen/cdxgen 13.5.0 → 13.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -10
- package/bin/audit.js +7 -4
- package/bin/cdxgen.js +260 -37
- package/bin/convert.js +146 -22
- package/bin/evinse.js +28 -3
- package/bin/repl.js +47 -3
- package/bin/sign.js +211 -34
- package/bin/tracebom.js +18 -6
- package/bin/validate.js +24 -3
- package/bin/verify.js +113 -5
- package/data/behavior-taxonomy.schema.json +1491 -0
- package/data/cyclonedx-2.0-bundled.schema.json +18606 -5528
- package/data/cyclonedx-2.0-cryptography-defs.schema.json +857 -0
- package/data/license-aliases.json +24 -2
- package/data/pqc-migration.json +239 -0
- package/data/remediations.json +176 -0
- package/data/rules/ai-bom.yaml +1 -1
- package/data/rules/brotli-decoder.yaml +107 -0
- package/data/rules/cbom-security.yaml +4 -3
- package/data/rules/package-integrity.yaml +28 -0
- package/data/rules/vscode-extensions.yaml +75 -0
- package/data/spdx-license-list.json +121 -7
- package/data/spdx-licenses.json +69 -0
- package/data/spdx.schema.json +845 -2
- package/lib/audit/index.js +25 -3
- package/lib/cli/bomAssembly.js +172 -4
- package/lib/cli/cliOptions.js +121 -17
- package/lib/cli/index.js +720 -902
- package/lib/cli/jsBom.js +156 -64
- package/lib/cli/jvmBom.js +602 -86
- package/lib/cli/managedBom.js +161 -19
- package/lib/cli/nativeBom.js +52 -5
- package/lib/core/boundedFile.js +344 -0
- package/lib/core/brotliProbe.js +182 -0
- package/lib/core/env.js +34 -0
- package/lib/core/fs.js +138 -3
- package/lib/core/globPatterns.js +218 -0
- package/lib/core/httpClient.js +98 -1
- package/lib/core/lockPaths.js +38 -0
- package/lib/core/paths.js +24 -1
- package/lib/core/processTree.js +100 -8
- package/lib/core/projectConfig.js +332 -25
- package/lib/core/toolRegistry.js +184 -0
- package/lib/ecosystems/cppEvidence.js +263 -106
- package/lib/ecosystems/cppIncludeResolver.js +16 -5
- package/lib/ecosystems/denoutils.js +2 -2
- package/lib/ecosystems/ecosystems.js +25 -10
- package/lib/ecosystems/gemHostProbe.js +301 -0
- package/lib/ecosystems/golem.js +3 -8
- package/lib/ecosystems/gradleutils.js +1909 -229
- package/lib/ecosystems/jsEvidence.js +90 -38
- package/lib/ecosystems/kosi.js +3 -5
- package/lib/ecosystems/npmVersionResolution.js +376 -0
- package/lib/ecosystems/parsers-bazel.js +107 -6
- package/lib/ecosystems/parsers-js.js +505 -22
- package/lib/ecosystems/parsers-misc.js +209 -20
- package/lib/ecosystems/parsers-python.js +178 -30
- package/lib/ecosystems/parsers-rust.js +117 -15
- package/lib/ecosystems/pythonutils.js +128 -2
- package/lib/ecosystems/remote/huggingface.js +22 -0
- package/lib/ecosystems/rubyutils.js +538 -31
- package/lib/ecosystems/rusi.js +2 -4
- package/lib/ecosystems/scalacliutils.js +2 -0
- package/lib/ecosystems/scalasem.js +798 -152
- package/lib/ecosystems/vendoredCode.js +237 -3
- package/lib/ecosystems/venvProbe.js +360 -0
- package/lib/evinser/evinser.js +536 -71
- package/lib/evinser/scalasem.js +5 -1
- package/lib/helpers/agenticToolutils.js +525 -94
- package/lib/helpers/bomSigner.js +43 -9
- package/lib/helpers/jssSigner.js +1276 -0
- package/lib/helpers/vsixutils.js +1574 -315
- package/lib/inventory/agentBlueprint.js +193 -0
- package/lib/inventory/agentToolNames.js +145 -0
- package/lib/inventory/aiCollector.js +153 -7
- package/lib/inventory/aiInventory.js +44 -8
- package/lib/inventory/aiProviders.js +324 -0
- package/lib/inventory/atomUtils.js +77 -0
- package/lib/inventory/bomUtils.js +8 -1
- package/lib/inventory/brotliDecoder.js +142 -0
- package/lib/inventory/buildToolRateLimit.js +1 -1
- package/lib/inventory/cbomutils.js +56 -7
- package/lib/inventory/ciParsers/githubActionsLock.js +821 -0
- package/lib/inventory/citations.js +31 -2
- package/lib/inventory/communityAiConfigParser.js +978 -80
- package/lib/inventory/cyclonedx20.js +152 -0
- package/lib/inventory/cyclonedx20Common.js +286 -0
- package/lib/inventory/cyclonedx20Derived.js +159 -0
- package/lib/inventory/cyclonedx20Parties.js +552 -0
- package/lib/inventory/cyclonedx20Read.js +768 -0
- package/lib/inventory/cyclonedx20ReadCommon.js +374 -0
- package/lib/inventory/cyclonedx20ReadComponents.js +692 -0
- package/lib/inventory/cyclonedx20ReadContext.js +380 -0
- package/lib/inventory/cyclonedx20ReadEvidence.js +466 -0
- package/lib/inventory/cyclonedx20ReadSections.js +599 -0
- package/lib/inventory/cyclonedx20Render.js +766 -0
- package/lib/inventory/cyclonedx20RenderComponents.js +716 -0
- package/lib/inventory/cyclonedx20RenderDefinitions.js +405 -0
- package/lib/inventory/cyclonedx20RenderEvidence.js +726 -0
- package/lib/inventory/cyclonedx20RenderHardware.js +203 -0
- package/lib/inventory/cyclonedx20RenderPatents.js +174 -0
- package/lib/inventory/cyclonedx20RenderRefIds.js +314 -0
- package/lib/inventory/cyclonedx20RenderSections.js +499 -0
- package/lib/inventory/cyclonedx20Tables.js +594 -0
- package/lib/inventory/deps.js +141 -13
- package/lib/inventory/dosai.js +375 -6
- package/lib/inventory/dosaiParsers.js +3 -6
- package/lib/inventory/dotnetRuntime.js +367 -0
- package/lib/inventory/ecosystemFormulationParsers.js +979 -0
- package/lib/inventory/envcontext.js +436 -48
- package/lib/inventory/evidenceUtils.js +13 -1
- package/lib/inventory/fetchBatch.js +1 -1
- package/lib/inventory/formulationParsers.js +124 -14
- package/lib/inventory/gtfobins.js +13 -0
- package/lib/inventory/hbom.js +45 -6
- package/lib/inventory/hbomLoader.js +166 -0
- package/lib/inventory/hostRuntimeProbe.js +686 -0
- package/lib/inventory/jvmLocalRepos.js +9 -2
- package/lib/inventory/jvmToolEnv.js +29 -0
- package/lib/inventory/licenseEnhancer.js +12 -0
- package/lib/inventory/mavenCentralMirror.js +534 -0
- package/lib/inventory/mcpConfigParser.js +5 -0
- package/lib/inventory/nodeBuildInfo.js +218 -0
- package/lib/inventory/nodeHostProbe.js +202 -0
- package/lib/inventory/occurrenceKey.js +90 -0
- package/lib/inventory/osPackageResolver.js +182 -0
- package/lib/inventory/phpBuildInfo.js +10 -59
- package/lib/inventory/phpHostProbe.js +32 -488
- package/lib/inventory/pqcMigration.js +426 -0
- package/lib/inventory/rubyBuildInfo.js +972 -0
- package/lib/inventory/rubyHostProbe.js +218 -0
- package/lib/inventory/rustFormulationParser.js +21 -10
- package/lib/inventory/scalaCoords.js +4 -3
- package/lib/inventory/scalaDedupe.js +440 -0
- package/lib/inventory/source.js +114 -8
- package/lib/managers/binary.js +337 -3
- package/lib/managers/docker.js +79 -0
- package/lib/parsers/huggingfaceManifest.js +9 -1
- package/lib/parsers/huggingfaceUtils.js +18 -0
- package/lib/parsers/kiroPermissions.js +166 -0
- package/lib/parsers/largeJson.js +28 -11
- package/lib/parsers/vscodeExtensionId.js +183 -0
- package/lib/server/server.js +48 -35
- package/lib/stages/postgen/postgen.js +41 -1
- package/lib/stages/postgen/ruleEngine.js +13 -5
- package/lib/stages/postgen/specVersionCompat.js +76 -0
- package/lib/stages/pregen/envAudit.js +1 -0
- package/lib/stages/pregen/pregen.js +114 -57
- package/lib/validator/bomValidator.js +14 -2
- package/lib/validator/complianceEngine.js +30 -3
- package/lib/validator/complianceRules.js +1416 -4
- package/lib/validator/generated/validate-1.6.mjs +1 -1
- package/lib/validator/generated/validate-1.7.mjs +1 -1
- package/lib/validator/generated/validate-2.0.mjs +57554 -13851
- package/lib/validator/index.js +49 -8
- package/lib/validator/reporters/json.js +6 -0
- package/package.json +11 -10
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts +6 -2
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +29 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +6 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +3 -18
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +15 -0
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/boundedFile.d.ts +100 -0
- package/types/lib/core/boundedFile.d.ts.map +1 -0
- package/types/lib/core/brotliProbe.d.ts +37 -0
- package/types/lib/core/brotliProbe.d.ts.map +1 -0
- package/types/lib/core/env.d.ts +14 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +4 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/globPatterns.d.ts +70 -0
- package/types/lib/core/globPatterns.d.ts.map +1 -0
- package/types/lib/core/httpClient.d.ts +24 -0
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/lockPaths.d.ts +19 -0
- package/types/lib/core/lockPaths.d.ts.map +1 -0
- package/types/lib/core/paths.d.ts +9 -0
- package/types/lib/core/paths.d.ts.map +1 -1
- package/types/lib/core/processTree.d.ts +17 -4
- package/types/lib/core/processTree.d.ts.map +1 -1
- package/types/lib/core/projectConfig.d.ts +47 -8
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/toolRegistry.d.ts +36 -0
- package/types/lib/core/toolRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +40 -13
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +2 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/gemHostProbe.d.ts +28 -0
- package/types/lib/ecosystems/gemHostProbe.d.ts.map +1 -0
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +294 -20
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +14 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmVersionResolution.d.ts +119 -0
- package/types/lib/ecosystems/npmVersionResolution.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-bazel.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +17 -20
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +19 -0
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +10 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +19 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +144 -12
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalasem.d.ts +58 -16
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +26 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -1
- package/types/lib/ecosystems/venvProbe.d.ts +40 -0
- package/types/lib/ecosystems/venvProbe.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +120 -13
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/scalasem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +53 -19
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +20 -3
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/helpers/jssSigner.d.ts +288 -0
- package/types/lib/helpers/jssSigner.d.ts.map +1 -0
- package/types/lib/helpers/vsixutils.d.ts +303 -19
- package/types/lib/helpers/vsixutils.d.ts.map +1 -1
- package/types/lib/inventory/agentBlueprint.d.ts +70 -0
- package/types/lib/inventory/agentBlueprint.d.ts.map +1 -0
- package/types/lib/inventory/agentToolNames.d.ts +51 -0
- package/types/lib/inventory/agentToolNames.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/aiProviders.d.ts +85 -0
- package/types/lib/inventory/aiProviders.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +19 -0
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/bomUtils.d.ts.map +1 -1
- package/types/lib/inventory/brotliDecoder.d.ts +58 -0
- package/types/lib/inventory/brotliDecoder.d.ts.map +1 -0
- package/types/lib/inventory/cbomutils.d.ts +17 -0
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts +101 -0
- package/types/lib/inventory/ciParsers/githubActionsLock.d.ts.map +1 -0
- package/types/lib/inventory/citations.d.ts +5 -0
- package/types/lib/inventory/citations.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/cyclonedx20.d.ts +99 -0
- package/types/lib/inventory/cyclonedx20.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts +102 -0
- package/types/lib/inventory/cyclonedx20Common.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts +74 -0
- package/types/lib/inventory/cyclonedx20Derived.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts +91 -0
- package/types/lib/inventory/cyclonedx20Parties.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts +51 -0
- package/types/lib/inventory/cyclonedx20Read.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts +69 -0
- package/types/lib/inventory/cyclonedx20ReadCommon.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts +77 -0
- package/types/lib/inventory/cyclonedx20ReadComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts +118 -0
- package/types/lib/inventory/cyclonedx20ReadContext.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts +40 -0
- package/types/lib/inventory/cyclonedx20ReadEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20ReadSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts +53 -0
- package/types/lib/inventory/cyclonedx20Render.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts +73 -0
- package/types/lib/inventory/cyclonedx20RenderComponents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts +29 -0
- package/types/lib/inventory/cyclonedx20RenderDefinitions.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts +110 -0
- package/types/lib/inventory/cyclonedx20RenderEvidence.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts +42 -0
- package/types/lib/inventory/cyclonedx20RenderHardware.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts +26 -0
- package/types/lib/inventory/cyclonedx20RenderPatents.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts +55 -0
- package/types/lib/inventory/cyclonedx20RenderRefIds.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts +45 -0
- package/types/lib/inventory/cyclonedx20RenderSections.d.ts.map +1 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts +134 -0
- package/types/lib/inventory/cyclonedx20Tables.d.ts.map +1 -0
- package/types/lib/inventory/deps.d.ts +35 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +36 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dotnetRuntime.d.ts +91 -0
- package/types/lib/inventory/dotnetRuntime.d.ts.map +1 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts +73 -0
- package/types/lib/inventory/ecosystemFormulationParsers.d.ts.map +1 -0
- package/types/lib/inventory/envcontext.d.ts +74 -12
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/gtfobins.d.ts.map +1 -1
- package/types/lib/inventory/hbom.d.ts +11 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomLoader.d.ts +54 -0
- package/types/lib/inventory/hbomLoader.d.ts.map +1 -1
- package/types/lib/inventory/hostRuntimeProbe.d.ts +44 -0
- package/types/lib/inventory/hostRuntimeProbe.d.ts.map +1 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts +5 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +12 -0
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/licenseEnhancer.d.ts.map +1 -1
- package/types/lib/inventory/mavenCentralMirror.d.ts +170 -0
- package/types/lib/inventory/mavenCentralMirror.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/nodeBuildInfo.d.ts +95 -0
- package/types/lib/inventory/nodeBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/nodeHostProbe.d.ts +15 -0
- package/types/lib/inventory/nodeHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/occurrenceKey.d.ts +52 -0
- package/types/lib/inventory/occurrenceKey.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +38 -0
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -1
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -1
- package/types/lib/inventory/pqcMigration.d.ts +84 -0
- package/types/lib/inventory/pqcMigration.d.ts.map +1 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts +271 -0
- package/types/lib/inventory/rubyBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/rubyHostProbe.d.ts +47 -0
- package/types/lib/inventory/rubyHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts +7 -2
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -1
- package/types/lib/inventory/scalaDedupe.d.ts +43 -0
- package/types/lib/inventory/scalaDedupe.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +25 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts +10 -1
- package/types/lib/parsers/huggingfaceManifest.d.ts.map +1 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts +12 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/kiroPermissions.d.ts +62 -0
- package/types/lib/parsers/kiroPermissions.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +4 -3
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/vscodeExtensionId.d.ts +48 -0
- package/types/lib/parsers/vscodeExtensionId.d.ts.map +1 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +7 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts +25 -0
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +12 -8
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts +5 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/complianceEngine.d.ts +4 -4
- package/types/lib/validator/complianceEngine.d.ts.map +1 -1
- package/types/lib/validator/complianceRules.d.ts +14 -2
- package/types/lib/validator/complianceRules.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -121,7 +121,9 @@ Sections include:
|
|
|
121
121
|
- [MCP Inventory](docs/MCP.md)
|
|
122
122
|
- [REPL Guide](docs/REPL.md)
|
|
123
123
|
- [Custom Properties](docs/CUSTOM_PROPERTIES.md)
|
|
124
|
-
- [
|
|
124
|
+
- [Coding Agent Plugin](agent-plugin/README.md)
|
|
125
|
+
- [Installing the plugin in coding agents](docs/AGENT_PLUGINS.md)
|
|
126
|
+
- [Agent CI recipes](docs/AGENT_CI.md)
|
|
125
127
|
- [Deprecations](docs/DEPRECATIONS.md)
|
|
126
128
|
- [Security Policy](SECURITY.md)
|
|
127
129
|
- [Threat Model](docs/THREAT_MODEL.md)
|
|
@@ -216,7 +218,7 @@ Common asset names:
|
|
|
216
218
|
#### Linux
|
|
217
219
|
|
|
218
220
|
```bash
|
|
219
|
-
VERSION="v13.
|
|
221
|
+
VERSION="v13.7.0"
|
|
220
222
|
ASSET="cdx-audit-linux-amd64"
|
|
221
223
|
BASE_URL="https://github.com/cdxgen/cdxgen/releases/download/${VERSION}"
|
|
222
224
|
|
|
@@ -230,7 +232,7 @@ chmod +x "${ASSET}"
|
|
|
230
232
|
#### macOS
|
|
231
233
|
|
|
232
234
|
```bash
|
|
233
|
-
VERSION="v13.
|
|
235
|
+
VERSION="v13.7.0"
|
|
234
236
|
ASSET="cdx-audit-darwin-arm64"
|
|
235
237
|
BASE_URL="https://github.com/cdxgen/cdxgen/releases/download/${VERSION}"
|
|
236
238
|
|
|
@@ -244,7 +246,7 @@ chmod +x "${ASSET}"
|
|
|
244
246
|
#### Windows (PowerShell)
|
|
245
247
|
|
|
246
248
|
```powershell
|
|
247
|
-
$Version = "v13.
|
|
249
|
+
$Version = "v13.7.0"
|
|
248
250
|
$Asset = "cdx-audit-windows-amd64.exe"
|
|
249
251
|
$BaseUrl = "https://github.com/cdxgen/cdxgen/releases/download/$Version"
|
|
250
252
|
|
|
@@ -269,7 +271,7 @@ steps:
|
|
|
269
271
|
env:
|
|
270
272
|
GH_TOKEN: ${{ github.token }}
|
|
271
273
|
run: |
|
|
272
|
-
gh release download v13.
|
|
274
|
+
gh release download v13.7.0 \
|
|
273
275
|
--repo cdxgen/cdxgen \
|
|
274
276
|
--pattern 'cdx-audit-linux-amd64' \
|
|
275
277
|
--pattern 'cdx-audit-linux-amd64.sha256'
|
|
@@ -296,7 +298,7 @@ winget install cdxgen
|
|
|
296
298
|
|
|
297
299
|
You can also use the cdxgen container image with node, deno, or bun runtime versions.
|
|
298
300
|
|
|
299
|
-
The default version uses Node.js
|
|
301
|
+
The default version uses Node.js 26
|
|
300
302
|
|
|
301
303
|
```bash
|
|
302
304
|
docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cdxgen/cdxgen:master -r /app -o /app/bom.json
|
|
@@ -337,7 +339,7 @@ npm install -g @cdxgen/cdxgen --ignore-scripts --min-release-age=2
|
|
|
337
339
|
**pnpm**:
|
|
338
340
|
|
|
339
341
|
```shell
|
|
340
|
-
pnpm add -g @cdxgen/cdxgen --
|
|
342
|
+
pnpm add -g @cdxgen/cdxgen --ignore-scripts --config.minimum-release-age=2880
|
|
341
343
|
```
|
|
342
344
|
|
|
343
345
|
**bun**:
|
|
@@ -621,16 +623,21 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
621
623
|
pnpm dlx @cdxgen/cdxgen-plugins-bin
|
|
622
624
|
```
|
|
623
625
|
|
|
624
|
-
##
|
|
626
|
+
## Coding agent plugin
|
|
625
627
|
|
|
626
|
-
The cdxgen toolkit is also packaged as a
|
|
628
|
+
The cdxgen toolkit is also packaged as a plugin for coding agents, so agents drive the correct command and flags, including the dry-run-first and no-auto-install safety constraints, instead of guessing. It is meant for Claude Code, OpenAI Codex, the GitHub Copilot CLI and app, Cursor, Gemini CLI, Kiro and opencode, and has been tried in Claude Code and Codex so far.
|
|
627
629
|
|
|
628
630
|
```shell
|
|
629
631
|
claude plugin marketplace add cdxgen/cdxgen
|
|
630
632
|
claude plugin install cdxgen@cdxgen-plugins
|
|
631
633
|
```
|
|
632
634
|
|
|
633
|
-
|
|
635
|
+
```shell
|
|
636
|
+
codex plugin marketplace add cdxgen/cdxgen
|
|
637
|
+
codex plugin add cdxgen@cdxgen-plugins
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
It ships skills covering SBOM generation, container and rootfs scans, OBOM/HBOM, CBOM, AI-BOM and MCP inventory, BOM auditing, signing, validation, conversion, evidence enrichment, runtime tracing, and Dependency-Track publishing. See [agent-plugin/README.md](agent-plugin/README.md) and the [installation guide](docs/AGENT_PLUGINS.md) for each client. To run cdxgen through an agent in GitHub Actions, see the [agent CI recipes](docs/AGENT_CI.md).
|
|
634
641
|
|
|
635
642
|
## Rust accelerator (cdxrs)
|
|
636
643
|
|
package/bin/audit.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { writeFileSync } from "node:fs";
|
|
4
3
|
import { dirname } from "node:path";
|
|
5
4
|
import process from "node:process";
|
|
6
5
|
|
|
@@ -13,6 +12,7 @@ import {
|
|
|
13
12
|
retrieveCdxgenVersion,
|
|
14
13
|
safeExistsSync,
|
|
15
14
|
safeMkdirSync,
|
|
15
|
+
safeWriteSync,
|
|
16
16
|
} from "../lib/ecosystems/utils.js";
|
|
17
17
|
|
|
18
18
|
const args = yargs(hideBin(process.argv))
|
|
@@ -193,7 +193,7 @@ function writeOrPrint(output, outputPath) {
|
|
|
193
193
|
if (!safeExistsSync(parentDir)) {
|
|
194
194
|
safeMkdirSync(parentDir, { recursive: true });
|
|
195
195
|
}
|
|
196
|
-
|
|
196
|
+
safeWriteSync(outputPath, output);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
(async () => {
|
|
@@ -235,10 +235,13 @@ function writeOrPrint(output, outputPath) {
|
|
|
235
235
|
report: args.report,
|
|
236
236
|
});
|
|
237
237
|
writeOrPrint(finalized.output, reportFile);
|
|
238
|
-
process.exit
|
|
238
|
+
// exitCode instead of process.exit lets a piped stdout write drain before
|
|
239
|
+
// the process ends, and the finally block below still runs.
|
|
240
|
+
process.exitCode = finalized.exitCode;
|
|
239
241
|
} catch (error) {
|
|
240
242
|
console.error(error.message);
|
|
241
|
-
process.exit
|
|
243
|
+
// exitCode instead of process.exit lets pending stderr output drain.
|
|
244
|
+
process.exitCode = 1;
|
|
242
245
|
} finally {
|
|
243
246
|
progressTracker.stop();
|
|
244
247
|
}
|
package/bin/cdxgen.js
CHANGED
|
@@ -83,13 +83,24 @@ import {
|
|
|
83
83
|
createOutputPlan,
|
|
84
84
|
getOutputDirectory,
|
|
85
85
|
} from "../lib/helpers/exportUtils.js";
|
|
86
|
+
import {
|
|
87
|
+
generateJssKeyPair,
|
|
88
|
+
signJssBom,
|
|
89
|
+
verifyJssBom,
|
|
90
|
+
} from "../lib/helpers/jssSigner.js";
|
|
86
91
|
import {
|
|
87
92
|
DEFAULT_CDX_SPEC_VERSION,
|
|
88
93
|
getSupportedCycloneDxComponentTypes,
|
|
94
|
+
isCycloneDx20SpecVersion,
|
|
89
95
|
isCycloneDxBom,
|
|
90
96
|
normalizeCycloneDxComponentTypeFilter,
|
|
91
97
|
toCycloneDxSpecVersionString,
|
|
92
98
|
} from "../lib/inventory/bomUtils.js";
|
|
99
|
+
import {
|
|
100
|
+
DEPENDENCY_TRACK_CDX20_ERROR,
|
|
101
|
+
getInternalBom,
|
|
102
|
+
refreshRenderedBom,
|
|
103
|
+
} from "../lib/inventory/cyclonedx20.js";
|
|
93
104
|
import {
|
|
94
105
|
displaySelfThreatModel,
|
|
95
106
|
printActivitySummary,
|
|
@@ -155,16 +166,37 @@ for (const configPattern of PROJECT_CONFIG_FILENAMES) {
|
|
|
155
166
|
continue;
|
|
156
167
|
}
|
|
157
168
|
try {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
169
|
+
const parsedConfig =
|
|
170
|
+
configPath.endsWith(".yml") || configPath.endsWith(".yaml")
|
|
171
|
+
? _load(fs.readFileSync(configPath, "utf-8"))
|
|
172
|
+
: JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
163
173
|
if (isSecureMode || DEBUG_MODE) {
|
|
164
174
|
console.log(`Config file '${configPath}' loaded successfully.`);
|
|
165
175
|
}
|
|
166
|
-
const sanitized = sanitizeProjectConfig(
|
|
176
|
+
const sanitized = sanitizeProjectConfig(parsedConfig, dirname(configPath));
|
|
167
177
|
config = sanitized.config;
|
|
178
|
+
for (const key of sanitized.operatorOnly) {
|
|
179
|
+
console.warn(
|
|
180
|
+
`\x1b[1;35mConfig file '${configPath}' sets '${key}', which only the command line or a CDXGEN_ environment variable may set. Ignoring it.\x1b[0m`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
for (const projectType of sanitized.hostScopeTypes) {
|
|
184
|
+
console.warn(
|
|
185
|
+
`\x1b[1;35mConfig file '${configPath}' selects the project type '${projectType}', which inventories this host rather than the project. Ignoring it. Pass '-t ${projectType}' on the command line if this is intentional.\x1b[0m`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
for (const key of sanitized.ignored) {
|
|
189
|
+
console.warn(
|
|
190
|
+
`Config file '${configPath}' sets '${key}', which is not an option a config file can set. Ignoring it.`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
for (const { key, pattern, reason } of sanitized.refusedPatterns) {
|
|
194
|
+
const shownPattern =
|
|
195
|
+
pattern.length > 80 ? `${pattern.slice(0, 77)}...` : pattern;
|
|
196
|
+
console.warn(
|
|
197
|
+
`\x1b[1;35mConfig file '${configPath}' sets the ${key} pattern '${shownPattern}', which ${reason}. Ignoring it. Pass the pattern on the command line if this is intentional.\x1b[0m`,
|
|
198
|
+
);
|
|
199
|
+
}
|
|
168
200
|
for (const entry of sanitized.rejected) {
|
|
169
201
|
console.warn(
|
|
170
202
|
`\x1b[1;35mConfig file '${configPath}' sets '${entry}', which points outside the project directory. Ignoring it. Pass the option on the command line if this is intentional.\x1b[0m`,
|
|
@@ -425,7 +457,7 @@ const args = _yargs
|
|
|
425
457
|
.option("generate-key-and-sign", {
|
|
426
458
|
type: "boolean",
|
|
427
459
|
description:
|
|
428
|
-
"Generate a public/private key pair for SBOM_SIGN_ALGORITHM
|
|
460
|
+
"Generate a public/private key pair for SBOM_SIGN_ALGORITHM and then sign the generated SBOM: with the JSON Signature Format (JSF, RS512 by default) at 1.x, or the JSON Signature Scheme (JSS, ITU-T X.590; Ed25519 by default) at --spec-version 2.0.",
|
|
429
461
|
})
|
|
430
462
|
.option("server", {
|
|
431
463
|
type: "boolean",
|
|
@@ -490,6 +522,10 @@ const args = _yargs
|
|
|
490
522
|
description: "Path for the usages slices file created by atom.",
|
|
491
523
|
hidden: true,
|
|
492
524
|
})
|
|
525
|
+
.option("callsites-slices-file", {
|
|
526
|
+
description: "Path for the callsites slices file created by atom.",
|
|
527
|
+
hidden: true,
|
|
528
|
+
})
|
|
493
529
|
.option("data-flow-slices-file", {
|
|
494
530
|
description: "Path for the data-flow slices file created by atom.",
|
|
495
531
|
hidden: true,
|
|
@@ -630,7 +666,7 @@ const args = _yargs
|
|
|
630
666
|
type: "boolean",
|
|
631
667
|
default: false,
|
|
632
668
|
description:
|
|
633
|
-
"Generate formulation section with git metadata and build
|
|
669
|
+
"Generate formulation section with git metadata, build tools and build inputs. On by default when CI=true, for BOM audits, the research and introspect profiles, OS project types and the cbom command; --no-include-formulation turns it off.",
|
|
634
670
|
})
|
|
635
671
|
.option("include-crypto", {
|
|
636
672
|
type: "boolean",
|
|
@@ -693,6 +729,8 @@ const args = _yargs
|
|
|
693
729
|
"suggest-build-tools",
|
|
694
730
|
"ruby-docker-install",
|
|
695
731
|
"resolve-gradle-distribution",
|
|
732
|
+
"gradle-prefer-lockfile",
|
|
733
|
+
"gradle-verification-fallback",
|
|
696
734
|
"jvm-tool-setup",
|
|
697
735
|
],
|
|
698
736
|
})
|
|
@@ -1204,6 +1242,21 @@ try {
|
|
|
1204
1242
|
console.error(error.message);
|
|
1205
1243
|
process.exit(1);
|
|
1206
1244
|
}
|
|
1245
|
+
// Dependency-Track ingests CycloneDX 1.x only. Refuse an upload (server URL
|
|
1246
|
+
// plus API key, the same condition the submission below uses) before
|
|
1247
|
+
// generating, so a long scan does not end in an upload that cannot succeed.
|
|
1248
|
+
// Server mode checks each request instead, since a request may choose its own
|
|
1249
|
+
// version.
|
|
1250
|
+
if (
|
|
1251
|
+
!options.server &&
|
|
1252
|
+
typeof options.serverUrl === "string" &&
|
|
1253
|
+
options.serverUrl.length > 0 &&
|
|
1254
|
+
options.apiKey &&
|
|
1255
|
+
isCycloneDx20SpecVersion(options.specVersion)
|
|
1256
|
+
) {
|
|
1257
|
+
console.error(DEPENDENCY_TRACK_CDX20_ERROR);
|
|
1258
|
+
process.exit(1);
|
|
1259
|
+
}
|
|
1207
1260
|
if (!options.projectType) {
|
|
1208
1261
|
thoughtLog(
|
|
1209
1262
|
"Ok, the user wants me to identify all the project types and generate a consolidated BOM document.",
|
|
@@ -1276,6 +1329,7 @@ if (options.lifecycle) {
|
|
|
1276
1329
|
const isHbomOnlyInvocation = isHbomOnlyProjectTypes(options.projectType);
|
|
1277
1330
|
const advancedWarnings = applyAdvancedOptionsImpl(options, {
|
|
1278
1331
|
isSecureMode: isSecureModeActive(),
|
|
1332
|
+
invokedCommandName,
|
|
1279
1333
|
});
|
|
1280
1334
|
// The config file comes from the working directory, usually the scanned
|
|
1281
1335
|
// project, so whether the project's own code may run stays the operator's
|
|
@@ -1640,6 +1694,99 @@ const signCycloneDxPayload = (jsonPayload, keyDir, target, options) => {
|
|
|
1640
1694
|
return signedBom;
|
|
1641
1695
|
};
|
|
1642
1696
|
|
|
1697
|
+
/**
|
|
1698
|
+
* Signs a CycloneDX 2.0 payload with JSS (ITU-T X.590) using the configured
|
|
1699
|
+
* or generated key: the root and the nested members the draft allows (see
|
|
1700
|
+
* lib/helpers/jssSigner.js). A generated key is checked against the fresh
|
|
1701
|
+
* signature, as the JSF path does.
|
|
1702
|
+
*
|
|
1703
|
+
* @param {string} jsonPayload Serialized CycloneDX 2.0 BOM
|
|
1704
|
+
* @param {string|undefined} keyDir Directory for --generate-key-and-sign keys
|
|
1705
|
+
* @param {string} target Output the signed BOM is written to (for the activity log)
|
|
1706
|
+
* @param {Object} options CLI options
|
|
1707
|
+
* @returns {Object} Signed BOM
|
|
1708
|
+
* @throws {Error} When signing was requested but cannot be completed
|
|
1709
|
+
*/
|
|
1710
|
+
const signJssPayload = (jsonPayload, keyDir, target, options) => {
|
|
1711
|
+
// Signing a supplied key needs SBOM_SIGN_ALGORITHM (see needsBomSigning);
|
|
1712
|
+
// only --generate-key-and-sign reaches here without one.
|
|
1713
|
+
const algorithm = readEnvironmentVariable("SBOM_SIGN_ALGORITHM") || "Ed25519";
|
|
1714
|
+
const sbomSignPrivateKey = readEnvironmentVariable("SBOM_SIGN_PRIVATE_KEY", {
|
|
1715
|
+
sensitive: true,
|
|
1716
|
+
});
|
|
1717
|
+
const sbomSignPrivateKeyBase64 = readEnvironmentVariable(
|
|
1718
|
+
"SBOM_SIGN_PRIVATE_KEY_BASE64",
|
|
1719
|
+
{ sensitive: true },
|
|
1720
|
+
);
|
|
1721
|
+
let privateKey;
|
|
1722
|
+
let publicKeyFile;
|
|
1723
|
+
if (options.generateKeyAndSign) {
|
|
1724
|
+
if (!keyDir) {
|
|
1725
|
+
throw new Error(
|
|
1726
|
+
"--generate-key-and-sign needs a file output (-o) to write the generated keys next to.",
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
publicKeyFile = join(keyDir, "public.key");
|
|
1730
|
+
const privateKeyFile = join(keyDir, "private.key");
|
|
1731
|
+
const generated = generateJssKeyPair(algorithm);
|
|
1732
|
+
safeWriteSync(
|
|
1733
|
+
publicKeyFile,
|
|
1734
|
+
generated.publicKey.export({ type: "spki", format: "pem" }),
|
|
1735
|
+
);
|
|
1736
|
+
// The private key is readable by the owner only.
|
|
1737
|
+
safeWriteSync(
|
|
1738
|
+
privateKeyFile,
|
|
1739
|
+
generated.privateKey.export({ type: "pkcs8", format: "pem" }),
|
|
1740
|
+
{ mode: 0o600 },
|
|
1741
|
+
);
|
|
1742
|
+
console.log(
|
|
1743
|
+
"Created public/private key pairs for testing purposes",
|
|
1744
|
+
publicKeyFile,
|
|
1745
|
+
privateKeyFile,
|
|
1746
|
+
);
|
|
1747
|
+
privateKey = generated.privateKey;
|
|
1748
|
+
} else if (sbomSignPrivateKey) {
|
|
1749
|
+
if (!safeExistsSync(sbomSignPrivateKey)) {
|
|
1750
|
+
throw new Error(
|
|
1751
|
+
`The SBOM_SIGN_PRIVATE_KEY file '${sbomSignPrivateKey}' was not found.`,
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
recordSensitiveFileRead(sbomSignPrivateKey, {
|
|
1755
|
+
label: "SBOM signing private key",
|
|
1756
|
+
});
|
|
1757
|
+
privateKey = fs.readFileSync(sbomSignPrivateKey);
|
|
1758
|
+
} else if (sbomSignPrivateKeyBase64) {
|
|
1759
|
+
privateKey = Buffer.from(sbomSignPrivateKeyBase64, "base64");
|
|
1760
|
+
} else {
|
|
1761
|
+
throw new Error(
|
|
1762
|
+
`Signing a CycloneDX 2.0 document needs a private key: set SBOM_SIGN_PRIVATE_KEY (PEM), SBOM_SIGN_PRIVATE_KEY_BASE64, or pass --generate-key-and-sign. Algorithm in use: ${algorithm}.`,
|
|
1763
|
+
);
|
|
1764
|
+
}
|
|
1765
|
+
thoughtLog(`Signing the BOM for "${target}" with JSS (${algorithm}).`);
|
|
1766
|
+
const signedBom = signJssBom(JSON.parse(jsonPayload), {
|
|
1767
|
+
algorithm,
|
|
1768
|
+
privateKey,
|
|
1769
|
+
});
|
|
1770
|
+
if (publicKeyFile) {
|
|
1771
|
+
const verdict = verifyJssBom(signedBom, {
|
|
1772
|
+
publicKey: fs.readFileSync(publicKeyFile, "utf8"),
|
|
1773
|
+
requireAll: true,
|
|
1774
|
+
});
|
|
1775
|
+
if (!verdict.valid) {
|
|
1776
|
+
throw new Error(
|
|
1777
|
+
`The new JSS signature does not verify with ${publicKeyFile}.`,
|
|
1778
|
+
);
|
|
1779
|
+
}
|
|
1780
|
+
console.log(
|
|
1781
|
+
"SBOM signature is verifiable natively with the public key and the algorithm",
|
|
1782
|
+
publicKeyFile,
|
|
1783
|
+
algorithm,
|
|
1784
|
+
);
|
|
1785
|
+
}
|
|
1786
|
+
recordActivity({ kind: "sign", status: "completed", target });
|
|
1787
|
+
return signedBom;
|
|
1788
|
+
};
|
|
1789
|
+
|
|
1643
1790
|
/**
|
|
1644
1791
|
* Signs the BOM for an output when signing is configured. A failure is
|
|
1645
1792
|
* recorded and returned so that the caller can stop with a non-zero exit
|
|
@@ -1660,6 +1807,24 @@ const signForOutput = (bomJson, jsonPayload, keyDir, target, options) => {
|
|
|
1660
1807
|
});
|
|
1661
1808
|
return { bomJson, jsonPayload };
|
|
1662
1809
|
}
|
|
1810
|
+
if (isCycloneDx20SpecVersion(bomJson?.specVersion || options?.specVersion)) {
|
|
1811
|
+
// A CycloneDX 2.0 document signs with JSS (ITU-T X.590) instead of JSF.
|
|
1812
|
+
try {
|
|
1813
|
+
const signedBom = signJssPayload(jsonPayload, keyDir, target, options);
|
|
1814
|
+
return {
|
|
1815
|
+
bomJson: signedBom,
|
|
1816
|
+
jsonPayload: stringifyJson(signedBom, options.jsonPretty),
|
|
1817
|
+
};
|
|
1818
|
+
} catch (err) {
|
|
1819
|
+
recordActivity({
|
|
1820
|
+
kind: "sign",
|
|
1821
|
+
reason: err.message,
|
|
1822
|
+
status: "failed",
|
|
1823
|
+
target,
|
|
1824
|
+
});
|
|
1825
|
+
return { bomJson, jsonPayload, signingError: err };
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1663
1828
|
try {
|
|
1664
1829
|
const signedBom = signCycloneDxPayload(
|
|
1665
1830
|
jsonPayload,
|
|
@@ -1998,7 +2163,10 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
1998
2163
|
hasCriticalFindings,
|
|
1999
2164
|
} = await import("../lib/stages/postgen/auditBom.js");
|
|
2000
2165
|
thoughtLog("Let's run security audit...");
|
|
2001
|
-
|
|
2166
|
+
// The audit and its annotations read the 1.x-shaped model; at 2.0 the
|
|
2167
|
+
// rendered document is refreshed once after the last mutation.
|
|
2168
|
+
const auditInternalBom = getInternalBom(bomNSData);
|
|
2169
|
+
const postAuditFindings = await auditBom(auditInternalBom, {
|
|
2002
2170
|
...options,
|
|
2003
2171
|
getBomWithOras,
|
|
2004
2172
|
});
|
|
@@ -2017,9 +2185,9 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2017
2185
|
}
|
|
2018
2186
|
}
|
|
2019
2187
|
if (postAuditFindings.length && options.specVersion >= 1.4) {
|
|
2020
|
-
|
|
2021
|
-
...(
|
|
2022
|
-
...formatAnnotations(postAuditFindings,
|
|
2188
|
+
auditInternalBom.annotations = [
|
|
2189
|
+
...(auditInternalBom.annotations || []),
|
|
2190
|
+
...formatAnnotations(postAuditFindings, auditInternalBom),
|
|
2023
2191
|
];
|
|
2024
2192
|
thoughtLog(
|
|
2025
2193
|
`Embedded ${postAuditFindings.length} audit findings as CycloneDX annotations`,
|
|
@@ -2053,7 +2221,7 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2053
2221
|
const requiredAuditTargetCount = collectAuditTargets(
|
|
2054
2222
|
[
|
|
2055
2223
|
{
|
|
2056
|
-
bomJson:
|
|
2224
|
+
bomJson: auditInternalBom,
|
|
2057
2225
|
source: filePath,
|
|
2058
2226
|
},
|
|
2059
2227
|
],
|
|
@@ -2074,7 +2242,7 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2074
2242
|
predictiveReport = await runAuditFromBoms(
|
|
2075
2243
|
[
|
|
2076
2244
|
{
|
|
2077
|
-
bomJson:
|
|
2245
|
+
bomJson: auditInternalBom,
|
|
2078
2246
|
source: filePath,
|
|
2079
2247
|
},
|
|
2080
2248
|
],
|
|
@@ -2111,14 +2279,14 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2111
2279
|
}
|
|
2112
2280
|
const predictiveAnnotations = formatPredictiveAnnotations(
|
|
2113
2281
|
predictiveReport,
|
|
2114
|
-
|
|
2282
|
+
auditInternalBom,
|
|
2115
2283
|
{
|
|
2116
2284
|
minSeverity: options.bomAuditMinSeverity,
|
|
2117
2285
|
},
|
|
2118
2286
|
);
|
|
2119
2287
|
if (predictiveAnnotations.length && options.specVersion >= 1.4) {
|
|
2120
|
-
|
|
2121
|
-
...(
|
|
2288
|
+
auditInternalBom.annotations = [
|
|
2289
|
+
...(auditInternalBom.annotations || []),
|
|
2122
2290
|
...predictiveAnnotations,
|
|
2123
2291
|
];
|
|
2124
2292
|
thoughtLog(
|
|
@@ -2161,9 +2329,11 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2161
2329
|
target: internalCycloneDxInputPath,
|
|
2162
2330
|
});
|
|
2163
2331
|
} else {
|
|
2332
|
+
// Evinse reads and writes the 1.x shape, so the temp input is the
|
|
2333
|
+
// internal model, not the rendered 2.0 document.
|
|
2164
2334
|
safeWriteSync(
|
|
2165
2335
|
internalCycloneDxInputPath,
|
|
2166
|
-
stringifyJson(bomNSData
|
|
2336
|
+
stringifyJson(getInternalBom(bomNSData), options.jsonPretty),
|
|
2167
2337
|
);
|
|
2168
2338
|
}
|
|
2169
2339
|
}
|
|
@@ -2193,7 +2363,7 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2193
2363
|
if (!options.projectType) {
|
|
2194
2364
|
const evidenceLanguage = evinserModule.defaultEvidenceLanguage(
|
|
2195
2365
|
filePath,
|
|
2196
|
-
bomNSData
|
|
2366
|
+
getInternalBom(bomNSData),
|
|
2197
2367
|
options,
|
|
2198
2368
|
);
|
|
2199
2369
|
if (evidenceLanguage) {
|
|
@@ -2205,10 +2375,17 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2205
2375
|
"Skipping the evidence analysis since the BOM lists no package in a language it supports. Pass -t to choose the language.",
|
|
2206
2376
|
);
|
|
2207
2377
|
if (bomNSData) {
|
|
2208
|
-
|
|
2209
|
-
|
|
2378
|
+
// The filter mutates the 1.x model; the rendered 2.0 document is
|
|
2379
|
+
// refreshed below, once, after this last mutation.
|
|
2380
|
+
const filteredBom = applyEvidenceBasedFilter(
|
|
2381
|
+
getInternalBom(bomNSData),
|
|
2210
2382
|
options,
|
|
2211
2383
|
);
|
|
2384
|
+
if (bomNSData.internalBomJson) {
|
|
2385
|
+
bomNSData.internalBomJson = filteredBom;
|
|
2386
|
+
} else {
|
|
2387
|
+
bomNSData.bomJson = filteredBom;
|
|
2388
|
+
}
|
|
2212
2389
|
}
|
|
2213
2390
|
} else {
|
|
2214
2391
|
const evinseOptions = evinserModule.buildEvinseOptions(
|
|
@@ -2216,6 +2393,12 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2216
2393
|
args,
|
|
2217
2394
|
internalCycloneDxInputPath || options.output,
|
|
2218
2395
|
);
|
|
2396
|
+
// The analysis reads the in-memory 1.x model. At 2.0 that model is
|
|
2397
|
+
// labelled 2.0 but is not a 2.0 document, so it is handed over
|
|
2398
|
+
// directly instead of being read back from the temporary file.
|
|
2399
|
+
if (bomNSData?.internalBomJson) {
|
|
2400
|
+
evinseOptions.inputBomJson = bomNSData.internalBomJson;
|
|
2401
|
+
}
|
|
2219
2402
|
try {
|
|
2220
2403
|
const dbObjMap = await evinserModule.prepareDB(evinseOptions);
|
|
2221
2404
|
if (dbObjMap) {
|
|
@@ -2225,16 +2408,31 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2225
2408
|
);
|
|
2226
2409
|
const evinseJson = await evinserModule.createEvinseFile(
|
|
2227
2410
|
sliceArtefacts,
|
|
2228
|
-
evinseOptions,
|
|
2411
|
+
{ ...evinseOptions, returnInternalModel: true },
|
|
2229
2412
|
);
|
|
2230
2413
|
// The scope filter is deferred until here so the analyzers get to
|
|
2231
|
-
// prove that an optional dependency is actually used.
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2414
|
+
// prove that an optional dependency is actually used. At 2.0
|
|
2415
|
+
// createEvinseFile runs postProcess again and would return the
|
|
2416
|
+
// rendered 2.0 document; `returnInternalModel` asks for the 1.x
|
|
2417
|
+
// model instead, which becomes the internal model and is
|
|
2418
|
+
// re-rendered below.
|
|
2419
|
+
const evinseInternalBom = evinseJson;
|
|
2420
|
+
if (bomNSData.internalBomJson) {
|
|
2421
|
+
bomNSData.internalBomJson = applyEvidenceBasedFilter(
|
|
2422
|
+
evinseInternalBom,
|
|
2423
|
+
options,
|
|
2424
|
+
);
|
|
2425
|
+
} else {
|
|
2426
|
+
bomNSData.bomJson = applyEvidenceBasedFilter(
|
|
2427
|
+
evinseInternalBom,
|
|
2428
|
+
options,
|
|
2429
|
+
);
|
|
2430
|
+
}
|
|
2431
|
+
if (options.print && evinseInternalBom) {
|
|
2432
|
+
printOccurrences(evinseInternalBom);
|
|
2433
|
+
printCallStack(evinseInternalBom);
|
|
2236
2434
|
printReachables(sliceArtefacts);
|
|
2237
|
-
printServices(
|
|
2435
|
+
printServices(evinseInternalBom);
|
|
2238
2436
|
}
|
|
2239
2437
|
}
|
|
2240
2438
|
} catch (err) {
|
|
@@ -2249,6 +2447,10 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2249
2447
|
}
|
|
2250
2448
|
}
|
|
2251
2449
|
}
|
|
2450
|
+
// The last post-postProcess mutation is done; at 2.0 the rendered document
|
|
2451
|
+
// is refreshed from the internal model once, before validation, signing
|
|
2452
|
+
// and writing. At 1.x this is a no-op.
|
|
2453
|
+
refreshRenderedBom(bomNSData, options);
|
|
2252
2454
|
// Perform automatic validation
|
|
2253
2455
|
if (options.validate && bomNSData?.bomJson) {
|
|
2254
2456
|
thoughtLog("Wait, let's check the generated BOM file for any issues.");
|
|
@@ -2302,7 +2504,12 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2302
2504
|
target: "spdx",
|
|
2303
2505
|
});
|
|
2304
2506
|
} else {
|
|
2305
|
-
|
|
2507
|
+
// The SPDX converter reads the 1.x shape; at 2.0 that is the internal
|
|
2508
|
+
// model.
|
|
2509
|
+
bomNSData.spdxJson = convertCycloneDxToSpdx(
|
|
2510
|
+
getInternalBom(bomNSData),
|
|
2511
|
+
options,
|
|
2512
|
+
);
|
|
2306
2513
|
recordActivity({
|
|
2307
2514
|
kind: "convert",
|
|
2308
2515
|
status: "completed",
|
|
@@ -2505,6 +2712,20 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2505
2712
|
status: "blocked",
|
|
2506
2713
|
target: options.serverUrl,
|
|
2507
2714
|
});
|
|
2715
|
+
} else if (isCycloneDx20SpecVersion(bomNSData.bomJson?.specVersion)) {
|
|
2716
|
+
// Unreachable from the CLI, which refuses this before generating; kept
|
|
2717
|
+
// so a 2.0 document can never reach Dependency-Track.
|
|
2718
|
+
recordActivity({
|
|
2719
|
+
kind: "submit",
|
|
2720
|
+
reason: DEPENDENCY_TRACK_CDX20_ERROR,
|
|
2721
|
+
status: "blocked",
|
|
2722
|
+
target: options.serverUrl,
|
|
2723
|
+
});
|
|
2724
|
+
console.error(DEPENDENCY_TRACK_CDX20_ERROR);
|
|
2725
|
+
if (cleanup) {
|
|
2726
|
+
cleanupSourceDir(srcDir);
|
|
2727
|
+
}
|
|
2728
|
+
process.exit(1);
|
|
2508
2729
|
} else {
|
|
2509
2730
|
try {
|
|
2510
2731
|
recordActivity({
|
|
@@ -2543,7 +2764,8 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2543
2764
|
try {
|
|
2544
2765
|
const { buildPublishCollectionPayload, publishTeaCollection } =
|
|
2545
2766
|
await import("../lib/ecosystems/tea.js");
|
|
2546
|
-
const parentComponent =
|
|
2767
|
+
const parentComponent =
|
|
2768
|
+
getInternalBom(bomNSData).metadata?.component || {};
|
|
2547
2769
|
const projectName =
|
|
2548
2770
|
options.teaCollectionName ||
|
|
2549
2771
|
parentComponent.name ||
|
|
@@ -2619,17 +2841,18 @@ const writeCycloneDxOutput = (jsonFile, bomJson, options) => {
|
|
|
2619
2841
|
thoughtLog("BOM file is also available in .proto format!");
|
|
2620
2842
|
}
|
|
2621
2843
|
}
|
|
2622
|
-
if (options.print && bomNSData
|
|
2623
|
-
|
|
2844
|
+
if (options.print && getInternalBom(bomNSData)?.components) {
|
|
2845
|
+
const printBom = getInternalBom(bomNSData);
|
|
2846
|
+
printSummary(printBom);
|
|
2624
2847
|
if (options.includeFormulation) {
|
|
2625
|
-
printFormulation(
|
|
2848
|
+
printFormulation(printBom);
|
|
2626
2849
|
}
|
|
2627
|
-
printDependencyTree(
|
|
2628
|
-
printTable(
|
|
2850
|
+
printDependencyTree(printBom);
|
|
2851
|
+
printTable(printBom);
|
|
2629
2852
|
// CBOM related print
|
|
2630
2853
|
if (options.includeCrypto) {
|
|
2631
|
-
printTable(
|
|
2632
|
-
printDependencyTree(
|
|
2854
|
+
printTable(printBom, ["cryptographic-asset"]);
|
|
2855
|
+
printDependencyTree(printBom, "provides");
|
|
2633
2856
|
}
|
|
2634
2857
|
}
|
|
2635
2858
|
if (isDryRun || DEBUG_MODE) {
|