@cyclonedx/cdxgen 12.3.3 → 12.4.1

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.
Files changed (175) hide show
  1. package/README.md +69 -25
  2. package/bin/audit.js +21 -7
  3. package/bin/cdxgen.js +270 -127
  4. package/bin/convert.js +34 -15
  5. package/bin/hbom.js +495 -0
  6. package/bin/repl.js +592 -37
  7. package/bin/validate.js +31 -4
  8. package/bin/verify.js +18 -5
  9. package/data/README.md +298 -25
  10. package/data/component-tags.json +6 -0
  11. package/data/crypto-oid.json +16 -0
  12. package/data/cyclonedx-2.0-bundled.schema.json +7182 -0
  13. package/data/predictive-audit-allowlist.json +11 -0
  14. package/data/queries-darwin.json +12 -1
  15. package/data/queries-win.json +7 -1
  16. package/data/queries.json +39 -2
  17. package/data/rules/ai-agent-governance.yaml +16 -0
  18. package/data/rules/asar-archives.yaml +150 -0
  19. package/data/rules/chrome-extensions.yaml +8 -0
  20. package/data/rules/ci-permissions.yaml +42 -18
  21. package/data/rules/container-risk.yaml +14 -7
  22. package/data/rules/dependency-sources.yaml +11 -0
  23. package/data/rules/hbom-compliance.yaml +325 -0
  24. package/data/rules/hbom-performance.yaml +307 -0
  25. package/data/rules/hbom-security.yaml +248 -0
  26. package/data/rules/host-topology.yaml +165 -0
  27. package/data/rules/mcp-servers.yaml +18 -3
  28. package/data/rules/obom-runtime.yaml +907 -22
  29. package/data/rules/package-integrity.yaml +14 -0
  30. package/data/rules/rootfs-hardening.yaml +179 -0
  31. package/data/rules/vscode-extensions.yaml +9 -0
  32. package/lib/audit/index.js +210 -8
  33. package/lib/audit/index.poku.js +332 -0
  34. package/lib/audit/reporters.js +222 -0
  35. package/lib/audit/targets.js +146 -1
  36. package/lib/audit/targets.poku.js +186 -0
  37. package/lib/cli/asar.poku.js +328 -0
  38. package/lib/cli/index.js +527 -99
  39. package/lib/cli/index.poku.js +1469 -212
  40. package/lib/evinser/evinser.js +14 -9
  41. package/lib/helpers/analyzer.js +1406 -29
  42. package/lib/helpers/analyzer.poku.js +342 -0
  43. package/lib/helpers/analyzerScope.js +712 -0
  44. package/lib/helpers/asarutils.js +1556 -0
  45. package/lib/helpers/asarutils.poku.js +443 -0
  46. package/lib/helpers/auditCategories.js +12 -0
  47. package/lib/helpers/auditCategories.poku.js +32 -0
  48. package/lib/helpers/bomUtils.js +155 -1
  49. package/lib/helpers/bomUtils.poku.js +79 -1
  50. package/lib/helpers/cbomutils.js +271 -1
  51. package/lib/helpers/cbomutils.poku.js +248 -5
  52. package/lib/helpers/display.js +291 -1
  53. package/lib/helpers/display.poku.js +149 -0
  54. package/lib/helpers/evidenceUtils.js +58 -0
  55. package/lib/helpers/evidenceUtils.poku.js +54 -0
  56. package/lib/helpers/exportUtils.js +9 -0
  57. package/lib/helpers/gtfobins.js +142 -8
  58. package/lib/helpers/gtfobins.poku.js +24 -1
  59. package/lib/helpers/hbom.js +710 -0
  60. package/lib/helpers/hbom.poku.js +496 -0
  61. package/lib/helpers/hbomAnalysis.js +268 -0
  62. package/lib/helpers/hbomAnalysis.poku.js +249 -0
  63. package/lib/helpers/hbomLoader.js +35 -0
  64. package/lib/helpers/hostTopology.js +803 -0
  65. package/lib/helpers/hostTopology.poku.js +363 -0
  66. package/lib/helpers/inventoryStats.js +69 -0
  67. package/lib/helpers/inventoryStats.poku.js +86 -0
  68. package/lib/helpers/lolbas.js +19 -1
  69. package/lib/helpers/lolbas.poku.js +23 -0
  70. package/lib/helpers/osqueryTransform.js +47 -0
  71. package/lib/helpers/osqueryTransform.poku.js +47 -0
  72. package/lib/helpers/plugins.js +350 -0
  73. package/lib/helpers/plugins.poku.js +57 -0
  74. package/lib/helpers/protobom.js +209 -45
  75. package/lib/helpers/protobom.poku.js +183 -5
  76. package/lib/helpers/protobomLoader.js +43 -0
  77. package/lib/helpers/protobomLoader.poku.js +31 -0
  78. package/lib/helpers/remote/dependency-track.js +36 -3
  79. package/lib/helpers/remote/dependency-track.poku.js +44 -0
  80. package/lib/helpers/source.js +24 -0
  81. package/lib/helpers/source.poku.js +32 -0
  82. package/lib/helpers/utils.js +1438 -93
  83. package/lib/helpers/utils.poku.js +846 -4
  84. package/lib/managers/binary.e2e.poku.js +367 -0
  85. package/lib/managers/binary.js +2293 -353
  86. package/lib/managers/binary.poku.js +1699 -1
  87. package/lib/managers/docker.js +201 -79
  88. package/lib/managers/docker.poku.js +337 -12
  89. package/lib/server/server.js +4 -28
  90. package/lib/stages/postgen/annotator.js +38 -0
  91. package/lib/stages/postgen/annotator.poku.js +107 -1
  92. package/lib/stages/postgen/auditBom.js +121 -18
  93. package/lib/stages/postgen/auditBom.poku.js +1366 -31
  94. package/lib/stages/postgen/hostTopologyAudit.poku.js +186 -0
  95. package/lib/stages/postgen/postgen.js +406 -8
  96. package/lib/stages/postgen/postgen.poku.js +484 -0
  97. package/lib/stages/postgen/ruleEngine.js +116 -0
  98. package/lib/stages/pregen/envAudit.js +14 -3
  99. package/lib/validator/bomValidator.js +90 -38
  100. package/lib/validator/bomValidator.poku.js +90 -0
  101. package/lib/validator/complianceRules.js +4 -2
  102. package/lib/validator/index.poku.js +14 -0
  103. package/package.json +23 -21
  104. package/types/bin/hbom.d.ts +3 -0
  105. package/types/bin/hbom.d.ts.map +1 -0
  106. package/types/bin/repl.d.ts +1 -1
  107. package/types/bin/repl.d.ts.map +1 -1
  108. package/types/lib/audit/index.d.ts +44 -0
  109. package/types/lib/audit/index.d.ts.map +1 -1
  110. package/types/lib/audit/reporters.d.ts +16 -0
  111. package/types/lib/audit/reporters.d.ts.map +1 -1
  112. package/types/lib/audit/targets.d.ts.map +1 -1
  113. package/types/lib/cli/index.d.ts +16 -0
  114. package/types/lib/cli/index.d.ts.map +1 -1
  115. package/types/lib/evinser/evinser.d.ts +4 -0
  116. package/types/lib/evinser/evinser.d.ts.map +1 -1
  117. package/types/lib/helpers/analyzer.d.ts +33 -0
  118. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  119. package/types/lib/helpers/analyzerScope.d.ts +11 -0
  120. package/types/lib/helpers/analyzerScope.d.ts.map +1 -0
  121. package/types/lib/helpers/asarutils.d.ts +34 -0
  122. package/types/lib/helpers/asarutils.d.ts.map +1 -0
  123. package/types/lib/helpers/auditCategories.d.ts +5 -0
  124. package/types/lib/helpers/auditCategories.d.ts.map +1 -1
  125. package/types/lib/helpers/bomUtils.d.ts +10 -0
  126. package/types/lib/helpers/bomUtils.d.ts.map +1 -1
  127. package/types/lib/helpers/cbomutils.d.ts +3 -2
  128. package/types/lib/helpers/cbomutils.d.ts.map +1 -1
  129. package/types/lib/helpers/display.d.ts.map +1 -1
  130. package/types/lib/helpers/evidenceUtils.d.ts +8 -0
  131. package/types/lib/helpers/evidenceUtils.d.ts.map +1 -0
  132. package/types/lib/helpers/exportUtils.d.ts.map +1 -1
  133. package/types/lib/helpers/gtfobins.d.ts +8 -0
  134. package/types/lib/helpers/gtfobins.d.ts.map +1 -1
  135. package/types/lib/helpers/hbom.d.ts +49 -0
  136. package/types/lib/helpers/hbom.d.ts.map +1 -0
  137. package/types/lib/helpers/hbomAnalysis.d.ts +76 -0
  138. package/types/lib/helpers/hbomAnalysis.d.ts.map +1 -0
  139. package/types/lib/helpers/hbomLoader.d.ts +7 -0
  140. package/types/lib/helpers/hbomLoader.d.ts.map +1 -0
  141. package/types/lib/helpers/hostTopology.d.ts +12 -0
  142. package/types/lib/helpers/hostTopology.d.ts.map +1 -0
  143. package/types/lib/helpers/inventoryStats.d.ts +11 -0
  144. package/types/lib/helpers/inventoryStats.d.ts.map +1 -0
  145. package/types/lib/helpers/lolbas.d.ts.map +1 -1
  146. package/types/lib/helpers/osqueryTransform.d.ts +3 -0
  147. package/types/lib/helpers/osqueryTransform.d.ts.map +1 -1
  148. package/types/lib/helpers/plugins.d.ts +58 -0
  149. package/types/lib/helpers/plugins.d.ts.map +1 -0
  150. package/types/lib/helpers/protobom.d.ts +5 -4
  151. package/types/lib/helpers/protobom.d.ts.map +1 -1
  152. package/types/lib/helpers/protobomLoader.d.ts +17 -0
  153. package/types/lib/helpers/protobomLoader.d.ts.map +1 -0
  154. package/types/lib/helpers/remote/dependency-track.d.ts +10 -3
  155. package/types/lib/helpers/remote/dependency-track.d.ts.map +1 -1
  156. package/types/lib/helpers/source.d.ts.map +1 -1
  157. package/types/lib/helpers/utils.d.ts +45 -8
  158. package/types/lib/helpers/utils.d.ts.map +1 -1
  159. package/types/lib/managers/binary.d.ts +5 -0
  160. package/types/lib/managers/binary.d.ts.map +1 -1
  161. package/types/lib/managers/docker.d.ts.map +1 -1
  162. package/types/lib/server/server.d.ts +2 -1
  163. package/types/lib/server/server.d.ts.map +1 -1
  164. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  165. package/types/lib/stages/postgen/auditBom.d.ts +26 -1
  166. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
  167. package/types/lib/stages/postgen/postgen.d.ts +2 -1
  168. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  169. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
  170. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -1
  171. package/types/lib/third-party/arborist/lib/node.d.ts +23 -0
  172. package/types/lib/third-party/arborist/lib/node.d.ts.map +1 -1
  173. package/types/lib/validator/bomValidator.d.ts.map +1 -1
  174. package/types/lib/validator/complianceRules.d.ts.map +1 -1
  175. package/data/spdx-model-v3.0.1.jsonld +0 -15999
@@ -0,0 +1,367 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import process from "node:process";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+
8
+ import { assert, it } from "poku";
9
+
10
+ const managersDir = path.dirname(fileURLToPath(import.meta.url));
11
+ const cdxgenRoot = path.resolve(managersDir, "../..");
12
+ const pluginsRepoRoot = [
13
+ path.resolve(cdxgenRoot, ".."),
14
+ path.resolve(cdxgenRoot, "../cdxgen-plugins-bin"),
15
+ path.resolve(process.cwd(), ".."),
16
+ path.resolve(process.cwd(), "../cdxgen-plugins-bin"),
17
+ ].find((candidate) =>
18
+ existsSync(path.join(candidate, "thirdparty", "trivy", "main.go")),
19
+ );
20
+ const trivySourceDir = pluginsRepoRoot
21
+ ? path.join(pluginsRepoRoot, "thirdparty", "trivy")
22
+ : undefined;
23
+ const trustInspectorSourceDir = pluginsRepoRoot
24
+ ? path.join(pluginsRepoRoot, "thirdparty", "trustinspector")
25
+ : undefined;
26
+ const nerdctlPath =
27
+ process.env.CDXGEN_NERDCTL_PATH || "/Users/prabhu/.rd/bin/nerdctl";
28
+
29
+ function quoteForShell(value) {
30
+ return `'${String(value).replace(/'/g, `'"'"'`)}'`;
31
+ }
32
+
33
+ function runCommand(command, args, options = {}) {
34
+ const result = spawnSync(command, args, {
35
+ encoding: "utf-8",
36
+ maxBuffer: 20 * 1024 * 1024,
37
+ ...options,
38
+ });
39
+ if (result.status !== 0) {
40
+ throw new Error(
41
+ `${command} ${args.join(" ")} failed with status ${result.status}: ${result.stderr || result.stdout}`,
42
+ );
43
+ }
44
+ return result;
45
+ }
46
+
47
+ function buildTrivyBinary() {
48
+ const outputDir = mkdtempSync(path.join(tmpdir(), "trivy-cdxgen-bin-"));
49
+ const outputPath = path.join(outputDir, "trivy-cdxgen-test");
50
+ runCommand(
51
+ "bash",
52
+ ["-lc", `GOEXPERIMENT=jsonv2 go build -o ${quoteForShell(outputPath)}`],
53
+ {
54
+ cwd: trivySourceDir,
55
+ env: process.env,
56
+ },
57
+ );
58
+ return outputPath;
59
+ }
60
+
61
+ function buildTrustInspectorBinary() {
62
+ const outputDir = mkdtempSync(
63
+ path.join(tmpdir(), "trustinspector-cdxgen-bin-"),
64
+ );
65
+ const outputPath = path.join(outputDir, "trustinspector-cdxgen-test");
66
+ runCommand("go", ["build", "-o", outputPath], {
67
+ cwd: trustInspectorSourceDir,
68
+ env: process.env,
69
+ });
70
+ return outputPath;
71
+ }
72
+
73
+ function exportRootfsWithNerdctl(image, options = {}) {
74
+ const rootfsDir = mkdtempSync(path.join(tmpdir(), "cdxgen-rootfs-e2e-"));
75
+ const shellScript = [
76
+ "set -euo pipefail",
77
+ ...(options.skipPull
78
+ ? []
79
+ : [
80
+ `${quoteForShell(nerdctlPath)} pull ${quoteForShell(image)} >/dev/null`,
81
+ ]),
82
+ `cid=$(${quoteForShell(nerdctlPath)} create ${quoteForShell(image)})`,
83
+ `trap '${quoteForShell(nerdctlPath)} rm -f "$cid" >/dev/null 2>&1 || true' EXIT`,
84
+ `${quoteForShell(nerdctlPath)} export "$cid" | tar -xf - -C ${quoteForShell(rootfsDir)}`,
85
+ `${quoteForShell(nerdctlPath)} rm -f "$cid" >/dev/null 2>&1 || true`,
86
+ ].join("\n");
87
+ runCommand("bash", ["-lc", shellScript]);
88
+ return rootfsDir;
89
+ }
90
+
91
+ function buildImageWithNerdctl(tag, dockerfileContents) {
92
+ const buildContextDir = mkdtempSync(path.join(tmpdir(), "cdxgen-image-e2e-"));
93
+ writeFileSync(path.join(buildContextDir, "Dockerfile"), dockerfileContents);
94
+ runCommand(nerdctlPath, ["build", "-t", tag, buildContextDir]);
95
+ return buildContextDir;
96
+ }
97
+
98
+ function createTrustInspectorPluginsDir() {
99
+ const pluginsDir = mkdtempSync(path.join(tmpdir(), "cdxgen-empty-plugins-"));
100
+ writeFileSync(
101
+ path.join(pluginsDir, "plugins-manifest.json"),
102
+ JSON.stringify(
103
+ {
104
+ plugins: [
105
+ {
106
+ name: "trustinspector",
107
+ component: {
108
+ type: "application",
109
+ name: "trustinspector",
110
+ version: "2.1.0",
111
+ purl: "pkg:generic/github.com/cdxgen/cdxgen-plugins-bin/trustinspector-cdxgen@2.1.0",
112
+ "bom-ref":
113
+ "pkg:generic/github.com/cdxgen/cdxgen-plugins-bin/trustinspector-cdxgen@2.1.0",
114
+ },
115
+ },
116
+ ],
117
+ },
118
+ null,
119
+ 2,
120
+ ),
121
+ );
122
+ return pluginsDir;
123
+ }
124
+
125
+ async function importBinaryModule() {
126
+ return import(
127
+ `${pathToFileURL(path.join(managersDir, "binary.js")).href}?e2e=${Date.now()}`
128
+ );
129
+ }
130
+
131
+ function setTemporaryEnv(overrides) {
132
+ const previousEnv = {};
133
+ for (const [name, value] of Object.entries(overrides)) {
134
+ previousEnv[name] = process.env[name];
135
+ if (value === undefined) {
136
+ delete process.env[name];
137
+ continue;
138
+ }
139
+ process.env[name] = value;
140
+ }
141
+ return () => {
142
+ for (const [name, value] of Object.entries(previousEnv)) {
143
+ if (value === undefined) {
144
+ delete process.env[name];
145
+ continue;
146
+ }
147
+ process.env[name] = value;
148
+ }
149
+ };
150
+ }
151
+
152
+ function extractSrcFiles(components) {
153
+ return new Set(
154
+ (components || [])
155
+ .flatMap((component) => component.properties || [])
156
+ .filter((property) => property.name === "SrcFile")
157
+ .map((property) => property.value),
158
+ );
159
+ }
160
+
161
+ const canRunE2E = Boolean(pluginsRepoRoot) && existsSync(nerdctlPath);
162
+
163
+ await it("getOSPackages() end-to-end on alpine rootfs creates owned file components without duplicate unpackaged binaries", async () => {
164
+ if (!canRunE2E) {
165
+ return;
166
+ }
167
+ const trivyBinary = buildTrivyBinary();
168
+ const rootfsDir = exportRootfsWithNerdctl("docker.io/library/alpine:3.20");
169
+ const emptyPluginsDir = mkdtempSync(
170
+ path.join(tmpdir(), "cdxgen-empty-plugins-"),
171
+ );
172
+ const restoreEnv = setTemporaryEnv({
173
+ CDXGEN_PLUGINS_DIR: emptyPluginsDir,
174
+ TRIVY_CMD: trivyBinary,
175
+ });
176
+ try {
177
+ const { getOSPackages } = await importBinaryModule();
178
+ const result = await getOSPackages(rootfsDir, {
179
+ Env: [
180
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
181
+ ],
182
+ });
183
+
184
+ assert.ok(result.osPackages.length > 0);
185
+ assert.ok(result.osPackageFiles.length > 0);
186
+ assert.ok(
187
+ result.dependenciesList.some(
188
+ (dependency) =>
189
+ dependency.ref &&
190
+ Array.isArray(dependency.provides) &&
191
+ dependency.provides.length > 0,
192
+ ),
193
+ );
194
+ assert.ok(
195
+ result.osPackages.some((component) =>
196
+ (component.properties || []).some((property) =>
197
+ property.name.endsWith("Capability"),
198
+ ),
199
+ ),
200
+ );
201
+
202
+ const packagedFilePaths = extractSrcFiles(result.osPackageFiles);
203
+ for (const component of result.executables.concat(result.sharedLibs)) {
204
+ const srcFile = (component.properties || []).find(
205
+ (property) => property.name === "SrcFile",
206
+ )?.value;
207
+ assert.strictEqual(packagedFilePaths.has(srcFile), false);
208
+ }
209
+ } finally {
210
+ restoreEnv();
211
+ rmSync(emptyPluginsDir, { recursive: true, force: true });
212
+ rmSync(path.dirname(trivyBinary), { recursive: true, force: true });
213
+ rmSync(rootfsDir, { recursive: true, force: true });
214
+ }
215
+ });
216
+
217
+ await it("getOSPackages() end-to-end on debian rootfs surfaces dpkg capabilities", async () => {
218
+ if (!canRunE2E) {
219
+ return;
220
+ }
221
+ const trivyBinary = buildTrivyBinary();
222
+ const trustInspectorBinary = buildTrustInspectorBinary();
223
+ const rootfsDir = exportRootfsWithNerdctl("docker.io/library/debian:12-slim");
224
+ const emptyPluginsDir = createTrustInspectorPluginsDir();
225
+ const restoreEnv = setTemporaryEnv({
226
+ CDXGEN_PLUGINS_DIR: emptyPluginsDir,
227
+ TRIVY_CMD: trivyBinary,
228
+ TRUSTINSPECTOR_CMD: trustInspectorBinary,
229
+ });
230
+ try {
231
+ const { getOSPackages } = await importBinaryModule();
232
+ const result = await getOSPackages(rootfsDir, {
233
+ Env: [
234
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
235
+ ],
236
+ });
237
+
238
+ assert.ok(result.osPackages.length > 0);
239
+ assert.ok(
240
+ result.osPackages.some((component) =>
241
+ (component.properties || []).some((property) =>
242
+ property.name.endsWith("Capability"),
243
+ ),
244
+ ),
245
+ );
246
+ assert.ok(
247
+ result.osPackages.some(
248
+ (component) =>
249
+ component.supplier?.name ||
250
+ component.manufacturer?.name ||
251
+ (component.authors || []).length,
252
+ ),
253
+ );
254
+ assert.ok(
255
+ result.osPackages.some(
256
+ (component) =>
257
+ component.type === "data" &&
258
+ (component.properties || []).some(
259
+ (property) =>
260
+ property.name === "cdx:os:repo:type" &&
261
+ (property.value === "apt-source" ||
262
+ property.value === "ppa-source"),
263
+ ),
264
+ ),
265
+ );
266
+ assert.ok(
267
+ result.osPackages.some(
268
+ (component) =>
269
+ component.type === "cryptographic-asset" &&
270
+ component.cryptoProperties?.assetType === "related-crypto-material" &&
271
+ component.cryptoProperties?.relatedCryptoMaterialProperties?.type ===
272
+ "public-key",
273
+ ),
274
+ );
275
+ assert.ok(result.tools.some((tool) => tool.name === "trustinspector"));
276
+ assert.ok(
277
+ result.osPackages.some(
278
+ (component) =>
279
+ component.type === "cryptographic-asset" &&
280
+ (component.properties || []).some(
281
+ (property) =>
282
+ property.name === "cdx:crypto:sourceType" &&
283
+ property.value === "repository-keyring",
284
+ ),
285
+ ),
286
+ );
287
+ } finally {
288
+ restoreEnv();
289
+ rmSync(emptyPluginsDir, { recursive: true, force: true });
290
+ rmSync(path.dirname(trivyBinary), { recursive: true, force: true });
291
+ rmSync(path.dirname(trustInspectorBinary), {
292
+ recursive: true,
293
+ force: true,
294
+ });
295
+ rmSync(rootfsDir, { recursive: true, force: true });
296
+ }
297
+ });
298
+
299
+ await it("getOSPackages() end-to-end on ubuntu rootfs with ca-certificates emits certificate crypto assets", async () => {
300
+ if (!canRunE2E) {
301
+ return;
302
+ }
303
+ const trivyBinary = buildTrivyBinary();
304
+ const trustInspectorBinary = buildTrustInspectorBinary();
305
+ const emptyPluginsDir = createTrustInspectorPluginsDir();
306
+ const imageTag = `cdxgen-e2e-cert-${Date.now()}`;
307
+ const buildContextDir = buildImageWithNerdctl(
308
+ imageTag,
309
+ [
310
+ "FROM docker.io/library/ubuntu:24.04",
311
+ "RUN apt-get update && \\",
312
+ " DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates && \\",
313
+ " rm -rf /var/lib/apt/lists/*",
314
+ ].join("\n"),
315
+ );
316
+ const rootfsDir = exportRootfsWithNerdctl(imageTag, { skipPull: true });
317
+ const restoreEnv = setTemporaryEnv({
318
+ CDXGEN_PLUGINS_DIR: emptyPluginsDir,
319
+ TRIVY_CMD: trivyBinary,
320
+ TRUSTINSPECTOR_CMD: trustInspectorBinary,
321
+ });
322
+ try {
323
+ const { getOSPackages } = await importBinaryModule();
324
+ const result = await getOSPackages(rootfsDir, {
325
+ Env: [
326
+ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
327
+ ],
328
+ });
329
+
330
+ const certificateAssets = result.osPackages.filter(
331
+ (component) =>
332
+ component.type === "cryptographic-asset" &&
333
+ component.cryptoProperties?.assetType === "certificate",
334
+ );
335
+ assert.ok(certificateAssets.length > 0);
336
+ assert.ok(result.tools.some((tool) => tool.name === "trustinspector"));
337
+ assert.ok(
338
+ certificateAssets.some(
339
+ (component) =>
340
+ (component.properties || []).some(
341
+ (property) => property.name === "SrcFile",
342
+ ) && component.cryptoProperties?.certificateProperties?.subjectName,
343
+ ),
344
+ );
345
+ assert.ok(
346
+ certificateAssets.some(
347
+ (component) =>
348
+ component.cryptoProperties?.certificateProperties
349
+ ?.certificateFormat === "X.509",
350
+ ),
351
+ );
352
+ } finally {
353
+ restoreEnv();
354
+ spawnSync(nerdctlPath, ["rmi", "-f", imageTag], {
355
+ encoding: "utf-8",
356
+ maxBuffer: 20 * 1024 * 1024,
357
+ });
358
+ rmSync(buildContextDir, { recursive: true, force: true });
359
+ rmSync(emptyPluginsDir, { recursive: true, force: true });
360
+ rmSync(path.dirname(trivyBinary), { recursive: true, force: true });
361
+ rmSync(path.dirname(trustInspectorBinary), {
362
+ recursive: true,
363
+ force: true,
364
+ });
365
+ rmSync(rootfsDir, { recursive: true, force: true });
366
+ }
367
+ });