@cyclonedx/cdxgen 12.3.1 → 12.3.3

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 (87) hide show
  1. package/README.md +6 -0
  2. package/bin/cdxgen.js +1 -2
  3. package/data/rules/ai-agent-governance.yaml +43 -0
  4. package/data/rules/ci-permissions.yaml +132 -0
  5. package/data/rules/dependency-sources.yaml +65 -5
  6. package/data/rules/mcp-servers.yaml +36 -2
  7. package/data/rules/package-integrity.yaml +22 -0
  8. package/lib/cli/index.js +436 -56
  9. package/lib/cli/index.poku.js +875 -2
  10. package/lib/helpers/agentFormulationParser.js +10 -3
  11. package/lib/helpers/agentFormulationParser.poku.js +42 -0
  12. package/lib/helpers/aiInventory.js +262 -0
  13. package/lib/helpers/aiInventory.poku.js +111 -0
  14. package/lib/helpers/analyzer.js +413 -54
  15. package/lib/helpers/analyzer.poku.js +117 -0
  16. package/lib/helpers/auditCategories.js +76 -0
  17. package/lib/helpers/chromextutils.js +25 -3
  18. package/lib/helpers/chromextutils.poku.js +68 -0
  19. package/lib/helpers/ciParsers/githubActions.js +79 -0
  20. package/lib/helpers/ciParsers/githubActions.poku.js +103 -0
  21. package/lib/helpers/communityAiConfigParser.js +15 -5
  22. package/lib/helpers/communityAiConfigParser.poku.js +71 -0
  23. package/lib/helpers/depsUtils.js +5 -0
  24. package/lib/helpers/depsUtils.poku.js +55 -0
  25. package/lib/helpers/display.js +50 -24
  26. package/lib/helpers/display.poku.js +70 -58
  27. package/lib/helpers/formulationParsers.js +26 -6
  28. package/lib/helpers/jsonLike.js +21 -20
  29. package/lib/helpers/jsonLike.poku.js +34 -0
  30. package/lib/helpers/mcpConfigParser.js +32 -16
  31. package/lib/helpers/mcpConfigParser.poku.js +104 -0
  32. package/lib/helpers/mcpDiscovery.js +13 -23
  33. package/lib/helpers/mcpDiscovery.poku.js +21 -0
  34. package/lib/helpers/propertySanitizer.js +121 -0
  35. package/lib/helpers/utils.js +953 -41
  36. package/lib/helpers/utils.poku.js +901 -1
  37. package/lib/managers/binary.js +16 -0
  38. package/lib/managers/binary.poku.js +1 -0
  39. package/lib/managers/docker.js +240 -16
  40. package/lib/managers/docker.poku.js +1142 -2
  41. package/lib/server/server.js +7 -4
  42. package/lib/server/server.poku.js +36 -1
  43. package/lib/stages/postgen/annotator.js +2 -1
  44. package/lib/stages/postgen/annotator.poku.js +15 -0
  45. package/lib/stages/postgen/auditBom.js +12 -6
  46. package/lib/stages/postgen/auditBom.poku.js +755 -6
  47. package/lib/stages/postgen/postgen.js +229 -6
  48. package/lib/stages/postgen/postgen.poku.js +180 -0
  49. package/package.json +2 -1
  50. package/types/lib/cli/index.d.ts +1 -0
  51. package/types/lib/cli/index.d.ts.map +1 -1
  52. package/types/lib/helpers/agentFormulationParser.d.ts +19 -0
  53. package/types/lib/helpers/agentFormulationParser.d.ts.map +1 -0
  54. package/types/lib/helpers/aiInventory.d.ts +23 -0
  55. package/types/lib/helpers/aiInventory.d.ts.map +1 -0
  56. package/types/lib/helpers/analyzer.d.ts +5 -0
  57. package/types/lib/helpers/analyzer.d.ts.map +1 -1
  58. package/types/lib/helpers/auditCategories.d.ts +12 -0
  59. package/types/lib/helpers/auditCategories.d.ts.map +1 -0
  60. package/types/lib/helpers/chromextutils.d.ts.map +1 -1
  61. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -1
  62. package/types/lib/helpers/communityAiConfigParser.d.ts +29 -0
  63. package/types/lib/helpers/communityAiConfigParser.d.ts.map +1 -0
  64. package/types/lib/helpers/depsUtils.d.ts.map +1 -1
  65. package/types/lib/helpers/display.d.ts +1 -0
  66. package/types/lib/helpers/display.d.ts.map +1 -1
  67. package/types/lib/helpers/formulationParsers.d.ts.map +1 -1
  68. package/types/lib/helpers/jsonLike.d.ts +4 -0
  69. package/types/lib/helpers/jsonLike.d.ts.map +1 -0
  70. package/types/lib/helpers/mcp.d.ts +29 -0
  71. package/types/lib/helpers/mcp.d.ts.map +1 -0
  72. package/types/lib/helpers/mcpConfigParser.d.ts +30 -0
  73. package/types/lib/helpers/mcpConfigParser.d.ts.map +1 -0
  74. package/types/lib/helpers/mcpDiscovery.d.ts +5 -0
  75. package/types/lib/helpers/mcpDiscovery.d.ts.map +1 -0
  76. package/types/lib/helpers/propertySanitizer.d.ts +3 -0
  77. package/types/lib/helpers/propertySanitizer.d.ts.map +1 -0
  78. package/types/lib/helpers/utils.d.ts +31 -0
  79. package/types/lib/helpers/utils.d.ts.map +1 -1
  80. package/types/lib/managers/binary.d.ts.map +1 -1
  81. package/types/lib/managers/docker.d.ts +3 -0
  82. package/types/lib/managers/docker.d.ts.map +1 -1
  83. package/types/lib/server/server.d.ts +1 -0
  84. package/types/lib/server/server.d.ts.map +1 -1
  85. package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
  86. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -1
  87. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
@@ -16,11 +16,13 @@ import { createContainerRiskProperties } from "../helpers/containerRisk.js";
16
16
  import { createGtfoBinsProperties } from "../helpers/gtfobins.js";
17
17
  import {
18
18
  adjustLicenseInformation,
19
+ attachIdentityTools,
19
20
  collectExecutables,
20
21
  collectSharedLibs,
21
22
  DEBUG_MODE,
22
23
  dirNameStr,
23
24
  extractPathEnv,
25
+ extractToolRefs,
24
26
  findLicenseId,
25
27
  getTmpDir,
26
28
  isDryRun,
@@ -465,6 +467,7 @@ export async function getOSPackages(src, imageConfig) {
465
467
  executables: [],
466
468
  osPackages: [],
467
469
  sharedLibs: [],
470
+ tools: [],
468
471
  };
469
472
  }
470
473
  const pkgList = [];
@@ -472,6 +475,7 @@ export async function getOSPackages(src, imageConfig) {
472
475
  const allTypes = new Set();
473
476
  const bundledSdks = new Set();
474
477
  const bundledRuntimes = new Set();
478
+ let tools = [];
475
479
  let binPaths = extractPathEnv(imageConfig?.Env);
476
480
  if (!binPaths?.length) {
477
481
  const rootBinPaths = getDirs(src, "{sbin,bin}", true, false);
@@ -633,6 +637,15 @@ export async function getOSPackages(src, imageConfig) {
633
637
  }
634
638
  }
635
639
  const tmpDependencies = {};
640
+ const toolRefs = extractToolRefs(
641
+ tmpBom?.metadata?.tools,
642
+ (tool) => tool?.name !== "cdxgen",
643
+ );
644
+ tools = (
645
+ Array.isArray(tmpBom?.metadata?.tools)
646
+ ? tmpBom.metadata.tools
647
+ : tmpBom?.metadata?.tools?.components || []
648
+ ).filter((tool) => tool?.["bom-ref"] && tool?.name !== "cdxgen");
636
649
  (tmpBom.dependencies || []).forEach((d) => {
637
650
  tmpDependencies[d.ref] = d.dependsOn;
638
651
  });
@@ -781,6 +794,7 @@ export async function getOSPackages(src, imageConfig) {
781
794
  console.log(err);
782
795
  }
783
796
  }
797
+ attachIdentityTools(comp, toolRefs);
784
798
  // Fix licenses
785
799
  if (
786
800
  comp.licenses &&
@@ -916,6 +930,7 @@ export async function getOSPackages(src, imageConfig) {
916
930
  ).toString();
917
931
  }
918
932
  newComp["bom-ref"] = decodeURIComponent(newComp.purl);
933
+ attachIdentityTools(newComp, toolRefs);
919
934
  pkgList.push(newComp);
920
935
  detectSdksRuntimes(newComp, bundledSdks, bundledRuntimes);
921
936
  }
@@ -968,6 +983,7 @@ export async function getOSPackages(src, imageConfig) {
968
983
  binPaths,
969
984
  executables,
970
985
  sharedLibs,
986
+ tools,
971
987
  };
972
988
  }
973
989
 
@@ -60,6 +60,7 @@ it("getOSPackages() returns empty collections and reports a blocked dry-run acti
60
60
  assert.deepStrictEqual(result.dependenciesList, []);
61
61
  assert.deepStrictEqual(result.binPaths, []);
62
62
  assert.deepStrictEqual(Array.from(result.allTypes), []);
63
+ assert.deepStrictEqual(result.tools, []);
63
64
  sinon.assert.calledWithMatch(recordActivity, {
64
65
  kind: "container",
65
66
  status: "blocked",
@@ -32,6 +32,13 @@ import { getDirs, getOnlyDirs } from "./containerutils.js";
32
32
 
33
33
  export const isWin = _platform() === "win32";
34
34
  export const DOCKER_HUB_REGISTRY = "docker.io";
35
+ // Docker commonly stores Hub credentials under index.docker.io or
36
+ // registry-1.docker.io while pulls target docker.io.
37
+ const DOCKER_HUB_REGISTRY_ALIASES = new Set([
38
+ DOCKER_HUB_REGISTRY,
39
+ "index.docker.io",
40
+ "registry-1.docker.io",
41
+ ]);
35
42
 
36
43
  /**
37
44
  * Encode a value as base64url (RFC 4648 §5) with padding.
@@ -42,6 +49,212 @@ export const DOCKER_HUB_REGISTRY = "docker.io";
42
49
  const toBase64Url = (value) =>
43
50
  Buffer.from(value).toString("base64").replace(/\+/g, "-").replace(/\//g, "_");
44
51
 
52
+ const normalizeRegistryPath = (registryPath) => {
53
+ if (!registryPath || registryPath === "/") {
54
+ return "";
55
+ }
56
+ let normalizedPath = registryPath.trim();
57
+ if (!normalizedPath.startsWith("/")) {
58
+ normalizedPath = `/${normalizedPath}`;
59
+ }
60
+ while (normalizedPath.endsWith("/")) {
61
+ normalizedPath = normalizedPath.slice(0, -1);
62
+ }
63
+ const lowerCasePath = normalizedPath.toLowerCase();
64
+ if (lowerCasePath.endsWith("/v1") || lowerCasePath.endsWith("/v2")) {
65
+ normalizedPath = normalizedPath.slice(0, -3);
66
+ }
67
+ return normalizedPath === "/" ? "" : normalizedPath;
68
+ };
69
+
70
+ const buildRegistryAuthority = (hostname, port) => {
71
+ if (!hostname) {
72
+ return undefined;
73
+ }
74
+ hostname = hostname.toLowerCase();
75
+ if (hostname.includes(":") && !hostname.startsWith("[")) {
76
+ hostname = `[${hostname}]`;
77
+ }
78
+ if (port) {
79
+ return `${hostname}:${port}`;
80
+ }
81
+ return hostname;
82
+ };
83
+
84
+ const parseRawRegistryAuthority = (authority) => {
85
+ if (!authority?.trim()) {
86
+ return undefined;
87
+ }
88
+ authority = authority.trim();
89
+ if (authority.startsWith("[")) {
90
+ const closingBracketIndex = authority.indexOf("]");
91
+ if (closingBracketIndex === -1) {
92
+ return undefined;
93
+ }
94
+ const hostname = authority.slice(0, closingBracketIndex + 1);
95
+ const portSuffix = authority.slice(closingBracketIndex + 1);
96
+ if (!portSuffix) {
97
+ return buildRegistryAuthority(hostname);
98
+ }
99
+ if (!/^:\d+$/.test(portSuffix)) {
100
+ return undefined;
101
+ }
102
+ return buildRegistryAuthority(hostname, portSuffix.slice(1));
103
+ }
104
+ const colonIndex = authority.lastIndexOf(":");
105
+ if (colonIndex > -1 && authority.indexOf(":") === colonIndex) {
106
+ const portCandidate = authority.slice(colonIndex + 1);
107
+ if (/^\d+$/.test(portCandidate)) {
108
+ return buildRegistryAuthority(
109
+ authority.slice(0, colonIndex),
110
+ portCandidate,
111
+ );
112
+ }
113
+ }
114
+ return buildRegistryAuthority(authority);
115
+ };
116
+
117
+ const parseRegistryReference = (registry) => {
118
+ if (!registry?.trim()) {
119
+ return undefined;
120
+ }
121
+ registry = registry.trim();
122
+ if (registry.includes("://")) {
123
+ if (!URL.canParse(registry)) {
124
+ return undefined;
125
+ }
126
+ const registryUrl = new URL(registry);
127
+ const authoritySource = registry
128
+ .slice(registry.indexOf("://") + 3)
129
+ .split("/")[0];
130
+ return {
131
+ authority: parseRawRegistryAuthority(authoritySource),
132
+ path: normalizeRegistryPath(registryUrl.pathname),
133
+ };
134
+ }
135
+ const slashIndex = registry.indexOf("/");
136
+ const authority =
137
+ slashIndex === -1 ? registry : registry.slice(0, slashIndex);
138
+ const registryPath = slashIndex === -1 ? "" : registry.slice(slashIndex);
139
+ if (!authority) {
140
+ return undefined;
141
+ }
142
+ try {
143
+ // Raw registry references such as host:port are not absolute URLs, so we
144
+ // add an https scheme only to parse the authority and optional port.
145
+ return {
146
+ authority: parseRawRegistryAuthority(authority),
147
+ path: normalizeRegistryPath(registryPath),
148
+ };
149
+ } catch (_err) {
150
+ return undefined;
151
+ }
152
+ };
153
+
154
+ const looksLikeImageReference = (value) => {
155
+ if (typeof value !== "string" || !value.trim()) {
156
+ return false;
157
+ }
158
+ value = value.trim();
159
+ if (value.includes("://")) {
160
+ return false;
161
+ }
162
+ if (!value.includes("/")) {
163
+ if (value.includes(":")) {
164
+ const tagOrPortSuffix = value.slice(value.lastIndexOf(":") + 1);
165
+ if (!/^\d+$/.test(tagOrPortSuffix)) {
166
+ return true;
167
+ }
168
+ return !parseRegistryReference(value)?.authority;
169
+ }
170
+ return !(
171
+ value.includes(".") ||
172
+ value === "localhost" ||
173
+ value.startsWith("[")
174
+ );
175
+ }
176
+ const firstSegment = value.split("/")[0];
177
+ return !(
178
+ parseRegistryReference(firstSegment)?.authority &&
179
+ (firstSegment.includes(".") ||
180
+ firstSegment.includes(":") ||
181
+ firstSegment === "localhost" ||
182
+ firstSegment.startsWith("["))
183
+ );
184
+ };
185
+
186
+ const resolveRequestedRegistryRef = (forRegistry, requestedRegistryRef) => {
187
+ const fallbackRegistry =
188
+ forRegistry || process.env.DOCKER_SERVER_ADDRESS || DOCKER_HUB_REGISTRY;
189
+ if (
190
+ typeof requestedRegistryRef !== "string" ||
191
+ !requestedRegistryRef.trim()
192
+ ) {
193
+ return fallbackRegistry;
194
+ }
195
+ requestedRegistryRef = requestedRegistryRef.trim();
196
+ if (requestedRegistryRef.includes("://")) {
197
+ return requestedRegistryRef;
198
+ }
199
+ return looksLikeImageReference(requestedRegistryRef)
200
+ ? fallbackRegistry
201
+ : requestedRegistryRef;
202
+ };
203
+
204
+ const extractRequestedRegistryRefFromPath = (path, forRegistry) => {
205
+ if (!path?.includes("?")) {
206
+ return resolveRequestedRegistryRef(forRegistry, forRegistry);
207
+ }
208
+ const queryString = path.slice(path.indexOf("?") + 1);
209
+ const requestedImageRef = new URLSearchParams(queryString).get("fromImage");
210
+ return resolveRequestedRegistryRef(
211
+ forRegistry,
212
+ requestedImageRef || forRegistry,
213
+ );
214
+ };
215
+
216
+ const normalizeRegistryReference = (registry) => {
217
+ const parsedRegistry = parseRegistryReference(registry);
218
+ if (!parsedRegistry?.authority) {
219
+ return undefined;
220
+ }
221
+ return parsedRegistry.path
222
+ ? `${parsedRegistry.authority}${parsedRegistry.path}`
223
+ : parsedRegistry.authority;
224
+ };
225
+
226
+ const registriesMatch = (configuredRegistry, requestedRegistry) => {
227
+ if (!requestedRegistry) {
228
+ return false;
229
+ }
230
+ const normalizedConfiguredRegistry =
231
+ parseRegistryReference(configuredRegistry);
232
+ const normalizedRequestedRegistry = parseRegistryReference(requestedRegistry);
233
+ if (
234
+ !normalizedConfiguredRegistry?.authority ||
235
+ !normalizedRequestedRegistry?.authority
236
+ ) {
237
+ return false;
238
+ }
239
+ const hostMatches =
240
+ normalizedConfiguredRegistry.authority ===
241
+ normalizedRequestedRegistry.authority ||
242
+ (DOCKER_HUB_REGISTRY_ALIASES.has(normalizedConfiguredRegistry.authority) &&
243
+ DOCKER_HUB_REGISTRY_ALIASES.has(normalizedRequestedRegistry.authority));
244
+ if (!hostMatches) {
245
+ return false;
246
+ }
247
+ if (!normalizedConfiguredRegistry.path) {
248
+ return true;
249
+ }
250
+ return (
251
+ normalizedConfiguredRegistry.path === normalizedRequestedRegistry.path ||
252
+ normalizedRequestedRegistry.path.startsWith(
253
+ `${normalizedConfiguredRegistry.path}/`,
254
+ )
255
+ );
256
+ };
257
+
45
258
  // Should we extract the tar image in non-strict mode
46
259
  const NON_STRICT_TAR_EXTRACT = ["true", "1"].includes(
47
260
  process?.env?.NON_STRICT_TAR_EXTRACT,
@@ -185,19 +398,21 @@ const REQUEST_TIMEOUT_SECS = 60000;
185
398
  *
186
399
  * @param {string} [forRegistry] Registry hostname (e.g. "registry-1.docker.io").
187
400
  * Defaults to DOCKER_SERVER_ADDRESS env var or "docker.io".
401
+ * @param {string} [requestedRegistryRef] Requested registry/image reference used
402
+ * to scope config.json auth matching. Unqualified images default to Docker Hub.
188
403
  * @returns {Object} Options object suitable for passing to `got`
189
404
  */
190
- const getDefaultOptions = (forRegistry) => {
405
+ const getDefaultOptions = (forRegistry, requestedRegistryRef = forRegistry) => {
191
406
  let authTokenSet = false;
192
407
  if (!forRegistry) {
193
408
  forRegistry = process.env.DOCKER_SERVER_ADDRESS ?? DOCKER_HUB_REGISTRY;
194
409
  }
195
- if (forRegistry) {
196
- forRegistry = forRegistry.replace("http://", "").replace("https://", "");
197
- if (forRegistry.includes("/")) {
198
- forRegistry = forRegistry.split("/")[0];
199
- }
200
- }
410
+ requestedRegistryRef = resolveRequestedRegistryRef(
411
+ forRegistry,
412
+ requestedRegistryRef,
413
+ );
414
+ const normalizedForRegistry =
415
+ parseRegistryReference(forRegistry)?.authority ?? forRegistry;
201
416
  const opts = {
202
417
  enableUnixSockets: true,
203
418
  throwHttpErrors: true,
@@ -227,12 +442,12 @@ const getDefaultOptions = (forRegistry) => {
227
442
  process.env.DOCKER_USER &&
228
443
  process.env.DOCKER_PASSWORD &&
229
444
  process.env.DOCKER_EMAIL &&
230
- forRegistry
445
+ normalizedForRegistry
231
446
  ) {
232
447
  const authPayload = {
233
448
  username: process.env.DOCKER_USER,
234
449
  email: process.env.DOCKER_EMAIL,
235
- serveraddress: forRegistry,
450
+ serveraddress: normalizedForRegistry,
236
451
  };
237
452
  if (process.env.DOCKER_USER === "<token>") {
238
453
  authPayload.IdentityToken = process.env.DOCKER_PASSWORD;
@@ -242,6 +457,7 @@ const getDefaultOptions = (forRegistry) => {
242
457
  opts.headers = {
243
458
  "X-Registry-Auth": toBase64Url(JSON.stringify(authPayload)),
244
459
  };
460
+ authTokenSet = true;
245
461
  }
246
462
  if (!authTokenSet && safeExistsSync(join(DOCKER_CONFIG, "config.json"))) {
247
463
  const configData = readFileSync(
@@ -254,7 +470,7 @@ const getDefaultOptions = (forRegistry) => {
254
470
  if (configJson.auths) {
255
471
  // Check if there are hardcoded tokens
256
472
  for (const serverAddress of Object.keys(configJson.auths)) {
257
- if (forRegistry && !serverAddress.includes(forRegistry)) {
473
+ if (!registriesMatch(serverAddress, requestedRegistryRef)) {
258
474
  continue;
259
475
  }
260
476
  if (configJson.auths[serverAddress].auth) {
@@ -293,7 +509,7 @@ const getDefaultOptions = (forRegistry) => {
293
509
  } else if (configJson.credHelpers) {
294
510
  // Support for credential helpers
295
511
  for (const serverAddress of Object.keys(configJson.credHelpers)) {
296
- if (forRegistry && !serverAddress.includes(forRegistry)) {
512
+ if (!registriesMatch(serverAddress, requestedRegistryRef)) {
297
513
  continue;
298
514
  }
299
515
  if (configJson.credHelpers[serverAddress]) {
@@ -535,7 +751,10 @@ export const makeRequest = async (path, method, forRegistry) => {
535
751
  }
536
752
  // Use the client's prefixUrl (set correctly by getConnection for
537
753
  // docker/podman). Only pass per-request auth headers and method options.
538
- const defaultOptions = getDefaultOptions(forRegistry);
754
+ const defaultOptions = getDefaultOptions(
755
+ forRegistry,
756
+ extractRequestedRegistryRefFromPath(path, forRegistry),
757
+ );
539
758
  const opts = {
540
759
  responseType: method === "GET" ? "json" : "buffer",
541
760
  resolveBodyOnly: true,
@@ -858,13 +1077,17 @@ export const getImage = async (fullImageName) => {
858
1077
  return localData;
859
1078
  };
860
1079
 
1080
+ /**
1081
+ * @typedef {{ path: string }} TarReadEntryLike
1082
+ */
1083
+
861
1084
  /**
862
1085
  * Warnings such as TAR_ENTRY_INFO are treated as errors in strict mode. While this is mostly desired, we can relax this
863
1086
  * requirement for one particular warning related to absolute paths.
864
1087
  * This callback function checks for absolute paths in the entry read from the archive and strips them using a custom
865
1088
  * method.
866
1089
  *
867
- * @param entry {tar.ReadEntry} ReadEntry object from node-tar
1090
+ * @param {TarReadEntryLike} entry ReadEntry object from node-tar
868
1091
  */
869
1092
  function handleAbsolutePath(entry) {
870
1093
  if (entry.path === "/" || win32.isAbsolute(entry.path)) {
@@ -1694,8 +1917,9 @@ export const removeImage = async (fullImageName, force = false) => {
1694
1917
  * if the helper is unavailable or returns an error
1695
1918
  */
1696
1919
  export const getCredsFromHelper = (exeSuffix, serverAddress) => {
1697
- if (registry_auth_keys[serverAddress]) {
1698
- return registry_auth_keys[serverAddress];
1920
+ const cacheKey = `${exeSuffix}:${normalizeRegistryReference(serverAddress) ?? serverAddress}`;
1921
+ if (registry_auth_keys[cacheKey]) {
1922
+ return registry_auth_keys[cacheKey];
1699
1923
  }
1700
1924
  let credHelperExe = `docker-credential-${exeSuffix}`;
1701
1925
  if (isWin) {
@@ -1726,7 +1950,7 @@ export const getCredsFromHelper = (exeSuffix, serverAddress) => {
1726
1950
  serveraddress: serverAddress,
1727
1951
  };
1728
1952
  const authKey = toBase64Url(JSON.stringify(fixedAuthPayload));
1729
- registry_auth_keys[serverAddress] = authKey;
1953
+ registry_auth_keys[cacheKey] = authKey;
1730
1954
  return authKey;
1731
1955
  } catch (_err) {
1732
1956
  return undefined;