@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/lib/audit/index.js
CHANGED
|
@@ -30,6 +30,10 @@ import {
|
|
|
30
30
|
getNonCycloneDxErrorMessage,
|
|
31
31
|
isCycloneDxBom,
|
|
32
32
|
} from "../inventory/bomUtils.js";
|
|
33
|
+
import {
|
|
34
|
+
formatReadLossNotice,
|
|
35
|
+
loadBomForAnalysis,
|
|
36
|
+
} from "../inventory/cyclonedx20.js";
|
|
33
37
|
import {
|
|
34
38
|
collectPolicyViolations,
|
|
35
39
|
loadPolicy,
|
|
@@ -122,10 +126,14 @@ const PYTHON_OBFUSCATION_PATTERN =
|
|
|
122
126
|
const PYTHON_SETUP_CMDCLASS_PATTERN = /\bcmdclass\s*=/i;
|
|
123
127
|
|
|
124
128
|
/**
|
|
125
|
-
* Read and validate a CycloneDX BOM file.
|
|
129
|
+
* Read and validate a CycloneDX BOM file. A CycloneDX 2.0 document is read
|
|
130
|
+
* into cdxgen's internal 1.x-shaped model, so the audit rules keep reading
|
|
131
|
+
* `components`, `bom-ref` and `metadata.component`; the number of losses
|
|
132
|
+
* the read reported is printed once on stderr, with the details in
|
|
133
|
+
* thoughtLog.
|
|
126
134
|
*
|
|
127
135
|
* @param {string} bomPath BOM file path
|
|
128
|
-
* @returns {object} parsed CycloneDX BOM
|
|
136
|
+
* @returns {object} parsed CycloneDX BOM in the 1.x shape
|
|
129
137
|
*/
|
|
130
138
|
export function loadBomFile(bomPath) {
|
|
131
139
|
const resolvedPath = resolve(bomPath);
|
|
@@ -138,7 +146,21 @@ export function loadBomFile(bomPath) {
|
|
|
138
146
|
if (!isCycloneDxBom(bomJson)) {
|
|
139
147
|
throw new Error(getNonCycloneDxErrorMessage(bomJson, "cdx-audit"));
|
|
140
148
|
}
|
|
141
|
-
|
|
149
|
+
let analysis;
|
|
150
|
+
try {
|
|
151
|
+
analysis = loadBomForAnalysis(bomJson);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
throw new Error(`Failed to read ${resolvedPath}: ${error.message}`);
|
|
154
|
+
}
|
|
155
|
+
const { internalBom, losses } = analysis;
|
|
156
|
+
if (losses.length) {
|
|
157
|
+
// stderr: stdout carries the --report json/sarif payload.
|
|
158
|
+
console.warn(formatReadLossNotice(losses));
|
|
159
|
+
for (const loss of losses) {
|
|
160
|
+
thoughtLog(`cdx-audit 2.0 loss at ${loss.pointer}: ${loss.reason}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return internalBom;
|
|
142
164
|
}
|
|
143
165
|
|
|
144
166
|
/**
|
package/lib/cli/bomAssembly.js
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
CDXGEN_VERSION,
|
|
26
26
|
frameworksList,
|
|
27
27
|
} from "../core/state.js";
|
|
28
|
+
import { getExecutedTools } from "../core/toolRegistry.js";
|
|
28
29
|
import {
|
|
29
30
|
isPkgTypeOnlyImport,
|
|
30
31
|
setNpmCleanedVersionProperty,
|
|
@@ -60,7 +61,7 @@ import {
|
|
|
60
61
|
} from "../inventory/purl.js";
|
|
61
62
|
import { repairPurl } from "../inventory/sbomDocument.js";
|
|
62
63
|
import { getLicenses } from "../inventory/spdx.js";
|
|
63
|
-
import { getBinaryBom } from "../managers/binary.js";
|
|
64
|
+
import { getBinaryBom, getPluginToolComponents } from "../managers/binary.js";
|
|
64
65
|
import { isValidIriReference } from "../parsers/iri.js";
|
|
65
66
|
|
|
66
67
|
/**
|
|
@@ -293,10 +294,85 @@ function anchorDetectedParent(
|
|
|
293
294
|
return anchored;
|
|
294
295
|
}
|
|
295
296
|
|
|
297
|
+
/**
|
|
298
|
+
* Builds the tool components for the external helpers and build tools this
|
|
299
|
+
* run executed, from the run-scoped registry (issue #598). Bundled plugin
|
|
300
|
+
* helpers are enriched with the manifest component of the plugin package that
|
|
301
|
+
* ships them, so the plugin package's version and identity travel with the
|
|
302
|
+
* helper. Empty when the run spawned nothing external, which keeps such BOMs
|
|
303
|
+
* byte-identical to the previous behaviour.
|
|
304
|
+
*
|
|
305
|
+
* @returns {object[]} Sorted CycloneDX tool components
|
|
306
|
+
*/
|
|
307
|
+
export const buildExternalToolComponents = () => {
|
|
308
|
+
const recordedTools = getExecutedTools();
|
|
309
|
+
if (!recordedTools.length) {
|
|
310
|
+
return [];
|
|
311
|
+
}
|
|
312
|
+
const recordedNames = recordedTools.map((tool) => tool.name);
|
|
313
|
+
const pluginComponents = getPluginToolComponents(recordedNames);
|
|
314
|
+
const pluginByName = new Map(
|
|
315
|
+
pluginComponents.map((component) => [component.name, component]),
|
|
316
|
+
);
|
|
317
|
+
const components = [];
|
|
318
|
+
for (const tool of recordedTools) {
|
|
319
|
+
const pluginComponent = pluginByName.get(tool.name);
|
|
320
|
+
if (pluginComponent?.["bom-ref"]) {
|
|
321
|
+
components.push(pluginComponent);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const component = {
|
|
325
|
+
type: "application",
|
|
326
|
+
name: tool.name,
|
|
327
|
+
};
|
|
328
|
+
if (tool.version) {
|
|
329
|
+
component.version = tool.version;
|
|
330
|
+
}
|
|
331
|
+
components.push(component);
|
|
332
|
+
}
|
|
333
|
+
return components;
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Drops the executed tools that are already present: a tool whose bom-ref or
|
|
338
|
+
* name matches an explicitly passed context tool, or whose bom-ref an earlier
|
|
339
|
+
* executed tool already carries (several bundled helpers can share one plugin
|
|
340
|
+
* package component). The context tools themselves are never touched.
|
|
341
|
+
*
|
|
342
|
+
* @param {object[]} contextTools Tool components passed in by the caller
|
|
343
|
+
* @param {object[]} executedTools Tool components from the run's registry
|
|
344
|
+
* @returns {object[]} The executed tools to append
|
|
345
|
+
*/
|
|
346
|
+
const newExecutedTools = (contextTools, executedTools) => {
|
|
347
|
+
const seenRefs = new Set();
|
|
348
|
+
const seenNames = new Set();
|
|
349
|
+
for (const component of contextTools) {
|
|
350
|
+
if (component?.["bom-ref"]) {
|
|
351
|
+
seenRefs.add(component["bom-ref"]);
|
|
352
|
+
}
|
|
353
|
+
if (component?.name) {
|
|
354
|
+
seenNames.add(component.name);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const unique = [];
|
|
358
|
+
for (const component of executedTools) {
|
|
359
|
+
const ref = component["bom-ref"];
|
|
360
|
+
if ((ref && seenRefs.has(ref)) || seenNames.has(component.name)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (ref) {
|
|
364
|
+
seenRefs.add(ref);
|
|
365
|
+
}
|
|
366
|
+
unique.push(component);
|
|
367
|
+
}
|
|
368
|
+
return unique;
|
|
369
|
+
};
|
|
370
|
+
|
|
296
371
|
/**
|
|
297
372
|
* Assembles the `metadata.tools` block, including the cdxgen tool entry and,
|
|
298
373
|
* for spec versions prior to 1.5, the legacy tools array. For spec version
|
|
299
|
-
* 1.6+ the author field is converted to the authors array.
|
|
374
|
+
* 1.6+ the author field is converted to the authors array. The tools this run
|
|
375
|
+
* executed follow the context tools, sorted by name, and cdxgen comes last.
|
|
300
376
|
*
|
|
301
377
|
* @param {object} options CLI options
|
|
302
378
|
* @param {object} [context={}] Additional context carrying existing components
|
|
@@ -304,6 +380,7 @@ function anchorDetectedParent(
|
|
|
304
380
|
* tools array (1.4) or a components array with tool components (1.5+)
|
|
305
381
|
*/
|
|
306
382
|
export const addToolsSection = (options, context = {}) => {
|
|
383
|
+
const externalTools = buildExternalToolComponents();
|
|
307
384
|
if (options.specVersion === 1.4) {
|
|
308
385
|
return [
|
|
309
386
|
{
|
|
@@ -311,6 +388,11 @@ export const addToolsSection = (options, context = {}) => {
|
|
|
311
388
|
name: "cdxgen",
|
|
312
389
|
version: CDXGEN_VERSION,
|
|
313
390
|
},
|
|
391
|
+
...newExecutedTools([], externalTools).map((tool) =>
|
|
392
|
+
tool.version
|
|
393
|
+
? { name: tool.name, version: tool.version }
|
|
394
|
+
: { name: tool.name },
|
|
395
|
+
),
|
|
314
396
|
];
|
|
315
397
|
}
|
|
316
398
|
let components = [];
|
|
@@ -331,6 +413,7 @@ export const addToolsSection = (options, context = {}) => {
|
|
|
331
413
|
} else if (tools && Object.keys(tools).length && tools.components) {
|
|
332
414
|
components = components.concat(tools.components);
|
|
333
415
|
}
|
|
416
|
+
components = components.concat(newExecutedTools(components, externalTools));
|
|
334
417
|
const cdxToolComponent = {
|
|
335
418
|
group: CDXGEN_TOOL_GROUP,
|
|
336
419
|
name: CDXGEN_TOOL_NAME,
|
|
@@ -524,7 +607,13 @@ export function addMetadata(parentComponent = {}, options = {}, context = {}) {
|
|
|
524
607
|
// We cannot use purl or bom-ref here since they would not match
|
|
525
608
|
// purl - could have application on one side and a different type
|
|
526
609
|
// bom-ref could have qualifiers on one side
|
|
527
|
-
|
|
610
|
+
// A purl subpath marks a separate project that declares the
|
|
611
|
+
// parent's coordinates, such as a second Maven project or a Gradle
|
|
612
|
+
// subproject with the same group, name and version.
|
|
613
|
+
const separateProject =
|
|
614
|
+
comp.purl?.includes("#") &&
|
|
615
|
+
comp.purl.split("#")[1] !== parentComponent.purl?.split("#")[1];
|
|
616
|
+
if (fullName !== parentFullName || separateProject) {
|
|
528
617
|
if (!comp["bom-ref"]) {
|
|
529
618
|
comp["bom-ref"] = `pkg:${comp.type}/${decodeURIComponent(
|
|
530
619
|
fullName,
|
|
@@ -1024,6 +1113,65 @@ export function hasNpmBinCommandEvidence(allImports, pkg) {
|
|
|
1024
1113
|
return false;
|
|
1025
1114
|
}
|
|
1026
1115
|
|
|
1116
|
+
/**
|
|
1117
|
+
* Return a CycloneDX organisational entity built from a collector-supplied
|
|
1118
|
+
* supplier or manufacturer, or undefined when the value is not a well-formed
|
|
1119
|
+
* entity.
|
|
1120
|
+
*
|
|
1121
|
+
* An entity needs a non-empty string name. When a url is present it must be
|
|
1122
|
+
* an array of valid IRI references; any other shape (a single string, an
|
|
1123
|
+
* array holding non-strings) drops the entity so the BOM stays schema
|
|
1124
|
+
* valid. Each contact is reduced to its string name, email and phone, and a
|
|
1125
|
+
* contact with none of them is left out. The entity bom-ref is not copied,
|
|
1126
|
+
* because CycloneDX 1.4 does not allow it there.
|
|
1127
|
+
*
|
|
1128
|
+
* @param {Object} entity Collector-supplied organisational entity
|
|
1129
|
+
* @returns {Object|undefined} Organisational entity, or undefined
|
|
1130
|
+
*/
|
|
1131
|
+
export function toOrganizationalEntity(entity) {
|
|
1132
|
+
if (!entity || typeof entity !== "object" || Array.isArray(entity)) {
|
|
1133
|
+
return undefined;
|
|
1134
|
+
}
|
|
1135
|
+
if (typeof entity.name !== "string" || !entity.name.trim().length) {
|
|
1136
|
+
return undefined;
|
|
1137
|
+
}
|
|
1138
|
+
const result = { name: entity.name.trim() };
|
|
1139
|
+
if (entity.url !== undefined) {
|
|
1140
|
+
if (
|
|
1141
|
+
!Array.isArray(entity.url) ||
|
|
1142
|
+
!entity.url.every(
|
|
1143
|
+
(u) => typeof u === "string" && u.length && isValidIriReference(u),
|
|
1144
|
+
)
|
|
1145
|
+
) {
|
|
1146
|
+
return undefined;
|
|
1147
|
+
}
|
|
1148
|
+
if (entity.url.length) {
|
|
1149
|
+
result.url = [...entity.url];
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
if (Array.isArray(entity.contact)) {
|
|
1153
|
+
const contacts = [];
|
|
1154
|
+
for (const contact of entity.contact) {
|
|
1155
|
+
if (!contact || typeof contact !== "object" || Array.isArray(contact)) {
|
|
1156
|
+
continue;
|
|
1157
|
+
}
|
|
1158
|
+
const reduced = {};
|
|
1159
|
+
for (const field of ["name", "email", "phone"]) {
|
|
1160
|
+
if (typeof contact[field] === "string" && contact[field].trim()) {
|
|
1161
|
+
reduced[field] = contact[field].trim();
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
if (Object.keys(reduced).length) {
|
|
1165
|
+
contacts.push(reduced);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
if (contacts.length) {
|
|
1169
|
+
result.contact = contacts;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
return result;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1027
1175
|
/**
|
|
1028
1176
|
* Given the specified package, create a CycloneDX component and add it to the list.
|
|
1029
1177
|
*/
|
|
@@ -1103,7 +1251,9 @@ export function addComponent(
|
|
|
1103
1251
|
const description = pkg.description || undefined;
|
|
1104
1252
|
let compScope = pkg.scope;
|
|
1105
1253
|
let isTypeOnlyPkg = false;
|
|
1106
|
-
|
|
1254
|
+
// addEvidenceForImports flags an installed version that none of the
|
|
1255
|
+
// project's imports resolve to; its name matching an import is no use.
|
|
1256
|
+
if (allImports && !pkg._npmImportsResolveElsewhere) {
|
|
1107
1257
|
const impPkgs = Object.keys(allImports);
|
|
1108
1258
|
const hasBinCommandEvidence = hasNpmBinCommandEvidence(allImports, pkg);
|
|
1109
1259
|
if (
|
|
@@ -1192,6 +1342,24 @@ export function addComponent(
|
|
|
1192
1342
|
delete component.swhid;
|
|
1193
1343
|
}
|
|
1194
1344
|
processHashes(pkg, component);
|
|
1345
|
+
// A collector that resolved the organisations behind a component keeps
|
|
1346
|
+
// them here: the AI collectors record the Hugging Face namespace that
|
|
1347
|
+
// published a model or dataset as the supplier, and the organisation
|
|
1348
|
+
// that created a model as the manufacturer. The supplier is a valid
|
|
1349
|
+
// component field in every spec version cdxgen emits; the manufacturer
|
|
1350
|
+
// arrived in CycloneDX 1.6. Only a well-formed organisational entity is
|
|
1351
|
+
// copied, so a collector that puts a string url or a build string on the
|
|
1352
|
+
// package cannot make the BOM fail schema validation.
|
|
1353
|
+
const supplier = toOrganizationalEntity(pkg.supplier);
|
|
1354
|
+
if (supplier) {
|
|
1355
|
+
component.supplier = supplier;
|
|
1356
|
+
}
|
|
1357
|
+
if (options.specVersion >= 1.6) {
|
|
1358
|
+
const manufacturer = toOrganizationalEntity(pkg.manufacturer);
|
|
1359
|
+
if (manufacturer) {
|
|
1360
|
+
component.manufacturer = manufacturer;
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1195
1363
|
// Upgrade authors section
|
|
1196
1364
|
if (options.specVersion >= 1.6 && component.author) {
|
|
1197
1365
|
const authorsList = [];
|
package/lib/cli/cliOptions.js
CHANGED
|
@@ -94,20 +94,35 @@ const POST_BUILD_SUPPORTED_PROJECT_TYPES = new Set([
|
|
|
94
94
|
// ---------------------------------------------------------------------------
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
* The formulation
|
|
98
|
-
*
|
|
99
|
-
*
|
|
97
|
+
* The notice for formulation that cdxgen turned on by itself. It names what
|
|
98
|
+
* turned formulation on, and, when the BOM is submitted to a server, the
|
|
99
|
+
* warning also names that server, as it does for an explicit
|
|
100
|
+
* --include-formulation.
|
|
100
101
|
*
|
|
102
|
+
* @param {object} options The options object
|
|
103
|
+
* @param {string} reasons What turned formulation on, such as "CI=true"
|
|
101
104
|
* @returns {OptionsWarning} The notice.
|
|
102
105
|
*/
|
|
103
|
-
function
|
|
106
|
+
function autoFormulationNotice(options, reasons) {
|
|
107
|
+
if (options.serverUrl) {
|
|
108
|
+
return {
|
|
109
|
+
level: "warn",
|
|
110
|
+
message: `WARNING: Automatically collecting formulation information for ${reasons}. The formulation section may include sensitive data such as emails and secrets. This data will be submitted to '${options.serverUrl}' automatically. Pass --no-include-formulation to leave it out.`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
104
113
|
return {
|
|
105
114
|
level: "info",
|
|
106
|
-
message:
|
|
107
|
-
"NOTE: Automatically collecting formulation information. The section may include sensitive data such as emails and secrets.\nPlease review the generated SBOM before distribution or LLM training.",
|
|
115
|
+
message: `NOTE: Automatically collecting formulation information for ${reasons}. The section may include sensitive data such as emails and secrets. Pass --no-include-formulation to leave it out.\nPlease review the generated SBOM before distribution or LLM training.`,
|
|
108
116
|
};
|
|
109
117
|
}
|
|
110
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Options objects whose formulation notes were already reported, so the CLI,
|
|
121
|
+
* which applies the advanced options twice, prints each note once.
|
|
122
|
+
*/
|
|
123
|
+
const formulationRefusalNoted = new WeakSet();
|
|
124
|
+
const secureFormulationNoteNoted = new WeakSet();
|
|
125
|
+
|
|
111
126
|
/**
|
|
112
127
|
* Check whether a value was explicitly provided by the user (i.e., is not
|
|
113
128
|
* the yargs default). Yargs always populates default values, so we cannot
|
|
@@ -400,6 +415,28 @@ function resolveIntrospectOption(args, argv) {
|
|
|
400
415
|
: undefined;
|
|
401
416
|
}
|
|
402
417
|
|
|
418
|
+
/**
|
|
419
|
+
* Whether the operator explicitly refused formulation with
|
|
420
|
+
* `--no-include-formulation`, `--include-formulation=false` or
|
|
421
|
+
* `CDXGEN_INCLUDE_FORMULATION=false`.
|
|
422
|
+
*
|
|
423
|
+
* @param {string[]} argv Raw command-line arguments the parser was given.
|
|
424
|
+
* @returns {boolean} True when formulation was refused explicitly.
|
|
425
|
+
*/
|
|
426
|
+
function isFormulationRefused(argv) {
|
|
427
|
+
return (
|
|
428
|
+
operatorOptionChoice("include-formulation", {
|
|
429
|
+
argv,
|
|
430
|
+
boolean: true,
|
|
431
|
+
env: {
|
|
432
|
+
CDXGEN_INCLUDE_FORMULATION: readEnvironmentVariable(
|
|
433
|
+
"CDXGEN_INCLUDE_FORMULATION",
|
|
434
|
+
),
|
|
435
|
+
},
|
|
436
|
+
}) === false
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
403
440
|
export function buildInitialOptions(
|
|
404
441
|
args,
|
|
405
442
|
{ filePath, isRemoteOrPurl, argv = process.argv, projectConfig },
|
|
@@ -427,6 +464,11 @@ export function buildInitialOptions(
|
|
|
427
464
|
// explicit --no-introspect stays `false` and beats both, while an
|
|
428
465
|
// unmentioned flag stays undefined so a profile can still enable it.
|
|
429
466
|
introspect: resolveIntrospectOption(args, argv),
|
|
467
|
+
// An explicit --no-include-formulation (or CDXGEN_INCLUDE_FORMULATION
|
|
468
|
+
// set to false) is the operator's refusal, which no automatic trigger
|
|
469
|
+
// such as CI=true, a profile, obom or cbom may override. The yargs
|
|
470
|
+
// default is also false, so only the raw arguments tell them apart.
|
|
471
|
+
includeFormulationRefused: isFormulationRefused(argv) || undefined,
|
|
430
472
|
// License normalization and enrichment are on by default; the only escape
|
|
431
473
|
// hatch is the corresponding environment variable.
|
|
432
474
|
licenseEnhance:
|
|
@@ -439,6 +481,10 @@ export function buildInitialOptions(
|
|
|
439
481
|
readEnvironmentVariable("CDXGEN_LICENSE_REF") === "true",
|
|
440
482
|
});
|
|
441
483
|
|
|
484
|
+
// A command default such as aibom's does not outrank the refusal either.
|
|
485
|
+
if (res.includeFormulationRefused) {
|
|
486
|
+
res.includeFormulation = false;
|
|
487
|
+
}
|
|
442
488
|
if (res.licenseEnhance !== undefined) {
|
|
443
489
|
process.env.CDXGEN_LICENSE_ENHANCE = String(res.licenseEnhance);
|
|
444
490
|
}
|
|
@@ -628,6 +674,8 @@ export function applyPostConstructionOverrides(options, context) {
|
|
|
628
674
|
* @param {object} options The options object
|
|
629
675
|
* @param {object} [context]
|
|
630
676
|
* @param {boolean} [context.isSecureMode] Whether cdxgen runs in secure mode
|
|
677
|
+
* @param {string} [context.invokedCommandName] Binary name (e.g. "cbom"),
|
|
678
|
+
* which can turn on formulation
|
|
631
679
|
* @returns {OptionsWarning[]} Warnings for the caller
|
|
632
680
|
*/
|
|
633
681
|
export function applyAdvancedOptions(options, context = {}) {
|
|
@@ -635,6 +683,7 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
635
683
|
const warnings = [];
|
|
636
684
|
const isHbomOnly = isHbomOnlyProjectTypes(options.projectType);
|
|
637
685
|
const includeFormulationBeforeProfiles = options.includeFormulation === true;
|
|
686
|
+
const formulationRefused = options.includeFormulationRefused === true;
|
|
638
687
|
const introspectExplicitlyDisabled = options.introspect === false;
|
|
639
688
|
|
|
640
689
|
// --- Profile expansion -------------------------------------------------
|
|
@@ -672,7 +721,7 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
672
721
|
options.introspectAnnotate = options.introspectAnnotate !== false;
|
|
673
722
|
// The ledger's own record of what ran; formulation is where a consumer
|
|
674
723
|
// looks for the build environment the SBOM was produced in.
|
|
675
|
-
options.includeFormulation = !isHbomOnly;
|
|
724
|
+
options.includeFormulation = !isHbomOnly && !formulationRefused;
|
|
676
725
|
options.evidence = true;
|
|
677
726
|
break;
|
|
678
727
|
case "ml-tiny":
|
|
@@ -752,17 +801,67 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
752
801
|
});
|
|
753
802
|
}
|
|
754
803
|
|
|
755
|
-
// --- BOM audit
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
804
|
+
// --- Auto-formulation: BOM audit, profiles, CI, obom and cbom ----------
|
|
805
|
+
// Formulation is included without a flag when a BOM audit reads it, when
|
|
806
|
+
// the research or introspect profile runs, in CI (CI=true), and for obom
|
|
807
|
+
// (an OS project type such as os, linux or windows) and cbom output
|
|
808
|
+
// (cdxgen#859). These runs are where the build environment and inputs are
|
|
809
|
+
// wanted next to the inventory. Formulation does not supply the CISA 2026
|
|
810
|
+
// generation context element: CISA-MIN-004 reads metadata.lifecycles.
|
|
811
|
+
// An explicit --no-include-formulation wins over every trigger.
|
|
812
|
+
const profileAddsFormulation =
|
|
813
|
+
["research", "introspect"].includes(options.profile) &&
|
|
814
|
+
!includeFormulationBeforeProfiles;
|
|
815
|
+
const autoFormulationReasons = [];
|
|
816
|
+
if (options.bomAudit) {
|
|
817
|
+
autoFormulationReasons.push("a BOM audit");
|
|
818
|
+
}
|
|
819
|
+
if (profileAddsFormulation) {
|
|
820
|
+
autoFormulationReasons.push(`the ${options.profile} profile`);
|
|
821
|
+
}
|
|
822
|
+
if ((readEnvironmentVariable("CI") || "").toLowerCase() === "true") {
|
|
823
|
+
autoFormulationReasons.push("CI=true");
|
|
824
|
+
}
|
|
825
|
+
if (hasOsProjectType(options.projectType)) {
|
|
826
|
+
autoFormulationReasons.push("an OS project type");
|
|
827
|
+
}
|
|
828
|
+
if (`${context.invokedCommandName || ""}`.includes("cbom")) {
|
|
829
|
+
autoFormulationReasons.push("the cbom command");
|
|
830
|
+
}
|
|
831
|
+
if (autoFormulationReasons.length && !isHbomOnly) {
|
|
832
|
+
const reasons = autoFormulationReasons.join(", ");
|
|
833
|
+
if (formulationRefused) {
|
|
834
|
+
options.includeFormulation = false;
|
|
835
|
+
if (!formulationRefusalNoted.has(options)) {
|
|
836
|
+
formulationRefusalNoted.add(options);
|
|
837
|
+
warnings.push({
|
|
838
|
+
level: "info",
|
|
839
|
+
message: `NOTE: Formulation stays off because it was refused explicitly (--no-include-formulation, --include-formulation=false or CDXGEN_INCLUDE_FORMULATION=false), although ${reasons} would include it.`,
|
|
840
|
+
});
|
|
841
|
+
}
|
|
761
842
|
} else if (!options.includeFormulation) {
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
843
|
+
if (options.serverUrl && secureMode) {
|
|
844
|
+
// Secure mode refuses to submit formulation to a server, so an
|
|
845
|
+
// automatic default must not turn a secure run into a failed one.
|
|
846
|
+
if (!secureFormulationNoteNoted.has(options)) {
|
|
847
|
+
secureFormulationNoteNoted.add(options);
|
|
848
|
+
warnings.push({
|
|
849
|
+
level: "info",
|
|
850
|
+
message: `NOTE: Formulation is not collected automatically for ${reasons} because secure mode does not submit formulation to '${options.serverUrl}'. Pass --include-formulation to request it.`,
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
} else {
|
|
854
|
+
warnings.push(autoFormulationNotice(options, reasons));
|
|
855
|
+
options.includeFormulation = true;
|
|
856
|
+
}
|
|
857
|
+
} else if (profileAddsFormulation) {
|
|
858
|
+
warnings.push(autoFormulationNotice(options, reasons));
|
|
859
|
+
}
|
|
860
|
+
// Formulation that no flag asked for leaves out the scanning host's
|
|
861
|
+
// certificates, authorized keys and keychain items (see
|
|
862
|
+
// addFormulationSection).
|
|
863
|
+
if (options.includeFormulation && !includeFormulationBeforeProfiles) {
|
|
864
|
+
options.formulationAutomatic = true;
|
|
766
865
|
}
|
|
767
866
|
}
|
|
768
867
|
|
|
@@ -795,6 +894,8 @@ export function applyAdvancedOptions(options, context = {}) {
|
|
|
795
894
|
* @param {object} [context.projectConfig] Sanitized config file contents,
|
|
796
895
|
* whose metadata properties merge
|
|
797
896
|
* with the other sources'
|
|
897
|
+
* @param {string[]} [context.argv] Raw command-line arguments,
|
|
898
|
+
* process.argv when absent
|
|
798
899
|
* @returns {{ options: object, warnings: OptionsWarning[] }}
|
|
799
900
|
*/
|
|
800
901
|
export function buildOptionsFromArgs(args, context) {
|
|
@@ -805,6 +906,7 @@ export function buildOptionsFromArgs(args, context) {
|
|
|
805
906
|
userSetSpecVersion,
|
|
806
907
|
isDryRun = false,
|
|
807
908
|
projectConfig,
|
|
909
|
+
argv,
|
|
808
910
|
} = context;
|
|
809
911
|
|
|
810
912
|
const expandedArgs = applyCommandNameDefaults(args, invokedCommandName);
|
|
@@ -812,6 +914,7 @@ export function buildOptionsFromArgs(args, context) {
|
|
|
812
914
|
filePath,
|
|
813
915
|
isRemoteOrPurl,
|
|
814
916
|
projectConfig,
|
|
917
|
+
...(argv ? { argv } : {}),
|
|
815
918
|
});
|
|
816
919
|
const phase3Warnings = applyPostConstructionOverrides(options, {
|
|
817
920
|
invokedCommandName,
|
|
@@ -820,6 +923,7 @@ export function buildOptionsFromArgs(args, context) {
|
|
|
820
923
|
});
|
|
821
924
|
const phase4Warnings = applyAdvancedOptions(options, {
|
|
822
925
|
isSecureMode: context.isSecureMode,
|
|
926
|
+
invokedCommandName,
|
|
823
927
|
});
|
|
824
928
|
|
|
825
929
|
return {
|