@kungfu-tech/buildchain 3.0.5 → 3.0.6-alpha.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 +31 -0
- package/actions/macos-credential-island/README.md +8 -0
- package/bin/buildchain.mjs +1 -1
- package/contracts/auditable-demo-media-profiles-v1.json +61 -0
- package/contracts/auditable-demo-scenario-v1.schema.json +164 -0
- package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +3 -3
- package/contracts/evidence/auditable-demo-web-delivery-v1.json +3 -3
- package/dist/site/buildchain-contract.json +107 -26
- package/dist/site/buildchain-site.json +121 -49
- package/dist/site/capability-registry.json +3 -3
- package/dist/site/cli-registry.json +9 -3
- package/dist/site/controller-registry.json +27 -3
- package/dist/site/kfd-claims.json +101 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +10 -9
- package/dist/site/node-api-registry.json +540 -31
- package/dist/site/page-registry.json +105 -29
- package/dist/site/public-surface-audit.json +184 -11
- package/dist/site/publication-authority-registry.json +62 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +13 -13
- package/dist/site/workflow-registry.json +118 -4
- package/docs/MAP.md +4 -1
- package/docs/auditable-demo.md +90 -7
- package/docs/aws-us-elastic-runner-burst-plane.md +151 -16
- package/docs/cli-reference.md +35 -2
- package/docs/dev-alpha-candidate-patrol.md +14 -5
- package/docs/dev-qualification-patrol.md +108 -0
- package/docs/node-api-reference.md +123 -72
- package/docs/publish-transaction.md +7 -5
- package/docs/release-flow.md +4 -0
- package/docs/release-governance.md +39 -0
- package/docs/release-propagation.md +93 -0
- package/docs/reusable-build-surface.md +53 -12
- package/docs/stable-candidate-patrol.md +5 -2
- package/package.json +1 -1
- package/packages/core/buildchain-contract.js +36 -1
- package/packages/core/buildchain-publication-authority.js +3 -0
- package/packages/core/public-surface-audit.js +4 -35
- package/packages/core/release-propagation-agent-entry.js +185 -0
- package/packages/core/release-propagation-pickup.js +387 -0
- package/packages/core/release-propagation-push.js +293 -0
- package/packages/core/release-propagation-release.js +61 -18
- package/packages/core/release-propagation-stage-evidence.js +36 -0
- package/packages/core/release-propagation-work.js +8 -4
- package/packages/core/release-propagation.js +27 -2
- package/packages/core/workflow-call-contract.js +308 -0
- package/packages/core/workflow-yaml-contract.js +272 -0
- package/scripts/artifact-signing-controller-core.mjs +525 -0
- package/scripts/artifact-signing-controller.mjs +302 -0
- package/scripts/artifact-signing-delegation.mjs +51 -3
- package/scripts/auditable-demo-platform.mjs +564 -0
- package/scripts/auditable-demo-renditions.mjs +7 -2
- package/scripts/auditable-demo-transport-smoke.mjs +176 -0
- package/scripts/auditable-demo.mjs +27 -21
- package/scripts/aws-macos-jit-controller-core.mjs +389 -0
- package/scripts/aws-macos-jit-controller-runtime.mjs +82 -0
- package/scripts/aws-macos-jit-controller.mjs +558 -0
- package/scripts/aws-macos-jit-job-controller.mjs +401 -0
- package/scripts/aws-windows-jit-campaign-core.mjs +296 -0
- package/scripts/aws-windows-jit-campaign.mjs +202 -0
- package/scripts/aws-windows-jit-controller-core.mjs +20 -2
- package/scripts/aws-windows-jit-controller.mjs +184 -109
- package/scripts/aws-windows-jit-core.mjs +21 -3
- package/scripts/aws-windows-jit.mjs +2 -0
- package/scripts/build-standalone-binary.mjs +6 -0
- package/scripts/buildchain-cli-help.mjs +2 -1
- package/scripts/capture-package-release-propagation.mjs +24 -1
- package/scripts/check-inventory.mjs +6 -0
- package/scripts/compiler-cache-evidence.mjs +90 -7
- package/scripts/dev-alpha-candidate-patrol.mjs +80 -5
- package/scripts/dev-pr-auto-merge.mjs +4 -4
- package/scripts/dev-qualification-patrol.mjs +594 -0
- package/scripts/dispatch-artifact-signing-authority.mjs +312 -61
- package/scripts/finalize-native-artifact-signing-result.mjs +37 -15
- package/scripts/generate-site-bundle.mjs +5 -0
- package/scripts/inspect-artifact-signing-requests.mjs +12 -0
- package/scripts/locked-source-checkout.mjs +17 -3
- package/scripts/release-propagation.mjs +150 -2
- package/scripts/run-lifecycle-core.mjs +25 -0
- package/scripts/site-capability-metadata.mjs +1 -1
- package/scripts/stable-candidate-patrol.mjs +30 -4
- package/scripts/workflow-call-contract.mjs +133 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
RECEIPT_CONTRACT,
|
|
8
|
+
artifactSigningControlRequestOutputs,
|
|
9
|
+
assertArtifactSigningControlRequestContext,
|
|
10
|
+
digestDocument,
|
|
11
|
+
normalizeControllerStatus,
|
|
12
|
+
readArtifactSigningControlRequest,
|
|
13
|
+
required,
|
|
14
|
+
sealArtifactSigningControlRequest,
|
|
15
|
+
validateArtifactSigningControlRequest,
|
|
16
|
+
validateArtifactSigningControllerReceipt,
|
|
17
|
+
} from "./artifact-signing-controller-core.mjs";
|
|
18
|
+
import {
|
|
19
|
+
assertArtifactSigningDelegationContext,
|
|
20
|
+
artifactSigningDelegationOutputs,
|
|
21
|
+
createArtifactSigningDelegation,
|
|
22
|
+
readArtifactSigningDelegation,
|
|
23
|
+
} from "./artifact-signing-delegation.mjs";
|
|
24
|
+
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
artifactSigningCorrelation,
|
|
28
|
+
artifactSigningRequestRoot,
|
|
29
|
+
artifactSigningControlRequestOutputs,
|
|
30
|
+
assertArtifactSigningControlRequestContext,
|
|
31
|
+
createArtifactSigningControlRequest,
|
|
32
|
+
readArtifactSigningControlRequest,
|
|
33
|
+
sealArtifactSigningControlRequest,
|
|
34
|
+
validateArtifactSigningControlRequest,
|
|
35
|
+
validateArtifactSigningControllerReceipt,
|
|
36
|
+
} from "./artifact-signing-controller-core.mjs";
|
|
37
|
+
|
|
38
|
+
function authorityRuntimeShaFromEnvironment() {
|
|
39
|
+
return process.env.BUILDCHAIN_AUTHORITY_RUNTIME_SHA || "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function settleArtifactSigningControl({
|
|
43
|
+
request,
|
|
44
|
+
authorityStatus = process.env.BUILDCHAIN_AUTHORITY_STATUS || "failed",
|
|
45
|
+
authorityRunId = process.env.BUILDCHAIN_AUTHORITY_RUN_ID || "",
|
|
46
|
+
authorityRuntimeSha = authorityRuntimeShaFromEnvironment(),
|
|
47
|
+
authorityRunUrl = process.env.BUILDCHAIN_AUTHORITY_RUN_URL || "",
|
|
48
|
+
authorityResultArtifact = process.env.BUILDCHAIN_SIGNING_RESULT_ARTIFACT ||
|
|
49
|
+
"",
|
|
50
|
+
authorityCorrelationId = process.env.BUILDCHAIN_AUTHORITY_CORRELATION_ID ||
|
|
51
|
+
"",
|
|
52
|
+
authorityConclusion = process.env.BUILDCHAIN_AUTHORITY_CONCLUSION || "",
|
|
53
|
+
controllerRepository = process.env.GITHUB_REPOSITORY,
|
|
54
|
+
controllerRunId = process.env.GITHUB_RUN_ID,
|
|
55
|
+
controllerRunAttempt = process.env.GITHUB_RUN_ATTEMPT || "1",
|
|
56
|
+
controllerJob = process.env.GITHUB_JOB || "artifact-signing-control",
|
|
57
|
+
controllerRunnerOs = process.env.RUNNER_OS || "Linux",
|
|
58
|
+
controllerStartedAt = process.env.BUILDCHAIN_CONTROLLER_STARTED_AT ||
|
|
59
|
+
new Date().toISOString(),
|
|
60
|
+
controllerCompletedAt = process.env.BUILDCHAIN_CONTROLLER_COMPLETED_AT ||
|
|
61
|
+
new Date().toISOString(),
|
|
62
|
+
receiptPath = process.env.BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_PATH,
|
|
63
|
+
delegationPath = process.env.BUILDCHAIN_SIGNING_DELEGATION_PATH,
|
|
64
|
+
} = {}) {
|
|
65
|
+
const control = validateArtifactSigningControlRequest(request);
|
|
66
|
+
const status = normalizeControllerStatus(authorityStatus);
|
|
67
|
+
const expectedStatus = control.request.count === 0 ? "skipped" : "succeeded";
|
|
68
|
+
const qualifying =
|
|
69
|
+
status === expectedStatus &&
|
|
70
|
+
(control.request.count === 0 || authorityConclusion === "success");
|
|
71
|
+
if (
|
|
72
|
+
authorityCorrelationId &&
|
|
73
|
+
authorityCorrelationId !== control.authority.correlationId
|
|
74
|
+
) {
|
|
75
|
+
throw new Error("authority correlation does not match control request");
|
|
76
|
+
}
|
|
77
|
+
if (
|
|
78
|
+
authorityResultArtifact &&
|
|
79
|
+
authorityResultArtifact !== control.authority.resultArtifact
|
|
80
|
+
) {
|
|
81
|
+
throw new Error("authority result artifact does not match control request");
|
|
82
|
+
}
|
|
83
|
+
const receipt = {
|
|
84
|
+
schemaVersion: 1,
|
|
85
|
+
contract: RECEIPT_CONTRACT,
|
|
86
|
+
requestDigest: control.digest,
|
|
87
|
+
source: control.source,
|
|
88
|
+
runtime: {
|
|
89
|
+
repository: control.runtime.repository,
|
|
90
|
+
sha: control.runtime.sha,
|
|
91
|
+
},
|
|
92
|
+
platform: control.platform,
|
|
93
|
+
request: control.request,
|
|
94
|
+
authority: {
|
|
95
|
+
repository: control.authority.repository,
|
|
96
|
+
runtimeSha: authorityRuntimeSha,
|
|
97
|
+
runId: control.request.count > 0 ? authorityRunId : "",
|
|
98
|
+
runUrl: control.request.count > 0 ? authorityRunUrl : "",
|
|
99
|
+
resultArtifact: control.request.count > 0 ? authorityResultArtifact : "",
|
|
100
|
+
correlationId: control.authority.correlationId,
|
|
101
|
+
conclusion:
|
|
102
|
+
control.request.count > 0
|
|
103
|
+
? authorityConclusion || status
|
|
104
|
+
: "not-required",
|
|
105
|
+
},
|
|
106
|
+
controller: {
|
|
107
|
+
repository: controllerRepository,
|
|
108
|
+
runId: controllerRunId,
|
|
109
|
+
runAttempt: Number(controllerRunAttempt),
|
|
110
|
+
job: controllerJob,
|
|
111
|
+
runnerOs: controllerRunnerOs,
|
|
112
|
+
startedAt: controllerStartedAt,
|
|
113
|
+
completedAt: controllerCompletedAt,
|
|
114
|
+
status,
|
|
115
|
+
},
|
|
116
|
+
qualifying,
|
|
117
|
+
};
|
|
118
|
+
receipt.digest = digestDocument(receipt);
|
|
119
|
+
const validatedReceipt = validateArtifactSigningControllerReceipt(receipt);
|
|
120
|
+
const resolvedReceiptPath = path.resolve(
|
|
121
|
+
required(receiptPath, "controller receipt path"),
|
|
122
|
+
);
|
|
123
|
+
fs.mkdirSync(path.dirname(resolvedReceiptPath), { recursive: true });
|
|
124
|
+
fs.writeFileSync(
|
|
125
|
+
resolvedReceiptPath,
|
|
126
|
+
`${JSON.stringify(validatedReceipt, null, 2)}\n`,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
let delegation = null;
|
|
130
|
+
if (validatedReceipt.qualifying) {
|
|
131
|
+
delegation = createArtifactSigningDelegation({
|
|
132
|
+
sourceRepository: control.source.repository,
|
|
133
|
+
sourceRunId: control.source.runId,
|
|
134
|
+
sourceRunAttempt: control.source.runAttempt,
|
|
135
|
+
sourceSha: control.source.sha,
|
|
136
|
+
sourceTreeSha: control.source.treeSha,
|
|
137
|
+
runtimeRepository: control.runtime.repository,
|
|
138
|
+
runtimeSha: control.runtime.sha,
|
|
139
|
+
platformId: control.platform.id,
|
|
140
|
+
platformName: control.platform.name,
|
|
141
|
+
requestCount: control.request.count,
|
|
142
|
+
requestArtifact: control.request.artifact,
|
|
143
|
+
requestRoot: control.request.root,
|
|
144
|
+
authorityRunId: validatedReceipt.authority.runId,
|
|
145
|
+
authorityRuntimeSha: validatedReceipt.authority.runtimeSha,
|
|
146
|
+
resultArtifact: validatedReceipt.authority.resultArtifact,
|
|
147
|
+
artifactName: control.artifact.name,
|
|
148
|
+
manifestArtifact: control.artifact.manifestArtifact,
|
|
149
|
+
diagnosticsArtifact: control.artifact.diagnosticsArtifact,
|
|
150
|
+
workingDirectory: control.workingDirectory,
|
|
151
|
+
controllerMode: "detached",
|
|
152
|
+
controllerReceiptDigest: validatedReceipt.digest,
|
|
153
|
+
});
|
|
154
|
+
const resolvedDelegationPath = path.resolve(
|
|
155
|
+
required(delegationPath, "delegation path"),
|
|
156
|
+
);
|
|
157
|
+
fs.mkdirSync(path.dirname(resolvedDelegationPath), { recursive: true });
|
|
158
|
+
fs.writeFileSync(
|
|
159
|
+
resolvedDelegationPath,
|
|
160
|
+
`${JSON.stringify(delegation, null, 2)}\n`,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
return { receipt: validatedReceipt, delegation };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function readArtifactSigningControllerReceipt(
|
|
167
|
+
inputPath = process.env.BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_PATH,
|
|
168
|
+
) {
|
|
169
|
+
const target = path.resolve(required(inputPath, "controller receipt path"));
|
|
170
|
+
return validateArtifactSigningControllerReceipt(
|
|
171
|
+
JSON.parse(fs.readFileSync(target, "utf8")),
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function assertArtifactSigningControllerReceipt({
|
|
176
|
+
request,
|
|
177
|
+
receipt,
|
|
178
|
+
delegation,
|
|
179
|
+
}) {
|
|
180
|
+
const control = validateArtifactSigningControlRequest(request);
|
|
181
|
+
const result = validateArtifactSigningControllerReceipt(receipt);
|
|
182
|
+
const finalDelegation = assertArtifactSigningDelegationContext(delegation, {
|
|
183
|
+
sourceRepository: control.source.repository,
|
|
184
|
+
sourceRunId: control.source.runId,
|
|
185
|
+
sourceRunAttempt: control.source.runAttempt,
|
|
186
|
+
sourceSha: control.source.sha,
|
|
187
|
+
runtimeRepository: control.runtime.repository,
|
|
188
|
+
runtimeSha: control.runtime.sha,
|
|
189
|
+
platformId: control.platform.id,
|
|
190
|
+
});
|
|
191
|
+
const comparisons = [
|
|
192
|
+
[result.requestDigest, control.digest, "control request digest"],
|
|
193
|
+
[result.source.treeSha, control.source.treeSha, "source tree SHA"],
|
|
194
|
+
[result.request.root, control.request.root, "request root"],
|
|
195
|
+
[result.request.artifact, control.request.artifact, "request artifact"],
|
|
196
|
+
[
|
|
197
|
+
result.authority.correlationId,
|
|
198
|
+
control.authority.correlationId,
|
|
199
|
+
"correlation",
|
|
200
|
+
],
|
|
201
|
+
[
|
|
202
|
+
result.authority.runId,
|
|
203
|
+
finalDelegation.authority.runId,
|
|
204
|
+
"authority run ID",
|
|
205
|
+
],
|
|
206
|
+
[
|
|
207
|
+
result.authority.runtimeSha,
|
|
208
|
+
finalDelegation.authority.runtimeSha,
|
|
209
|
+
"authority runtime SHA",
|
|
210
|
+
],
|
|
211
|
+
[
|
|
212
|
+
result.authority.resultArtifact,
|
|
213
|
+
finalDelegation.authority.resultArtifact,
|
|
214
|
+
"authority result artifact",
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
finalDelegation.controller.receiptDigest,
|
|
218
|
+
result.digest,
|
|
219
|
+
"controller receipt digest",
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
finalDelegation.request.root,
|
|
223
|
+
result.request.root,
|
|
224
|
+
"delegation request root",
|
|
225
|
+
],
|
|
226
|
+
];
|
|
227
|
+
for (const [actual, expected, label] of comparisons) {
|
|
228
|
+
if (actual !== expected) {
|
|
229
|
+
throw new Error(`artifact signing controller ${label} mismatch`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (!result.qualifying) {
|
|
233
|
+
throw new Error("artifact signing controller receipt is not qualifying");
|
|
234
|
+
}
|
|
235
|
+
return { request: control, receipt: result, delegation: finalDelegation };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function expectedContext() {
|
|
239
|
+
return {
|
|
240
|
+
sourceRepository: process.env.BUILDCHAIN_EXPECTED_SOURCE_REPOSITORY || "",
|
|
241
|
+
sourceRunId: process.env.BUILDCHAIN_EXPECTED_SOURCE_RUN_ID || "",
|
|
242
|
+
sourceRunAttempt: process.env.BUILDCHAIN_EXPECTED_SOURCE_RUN_ATTEMPT || "",
|
|
243
|
+
sourceSha: process.env.BUILDCHAIN_EXPECTED_SOURCE_SHA || "",
|
|
244
|
+
sourceTreeSha: process.env.BUILDCHAIN_EXPECTED_SOURCE_TREE_SHA || "",
|
|
245
|
+
runtimeRepository: process.env.BUILDCHAIN_EXPECTED_RUNTIME_REPOSITORY || "",
|
|
246
|
+
runtimeSha: process.env.BUILDCHAIN_EXPECTED_RUNTIME_SHA || "",
|
|
247
|
+
platformId: process.env.BUILDCHAIN_EXPECTED_PLATFORM_ID || "",
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (
|
|
252
|
+
process.argv[1] &&
|
|
253
|
+
import.meta.url === pathToFileURL(process.argv[1]).href
|
|
254
|
+
) {
|
|
255
|
+
try {
|
|
256
|
+
const mode = process.argv[2] || "seal";
|
|
257
|
+
if (mode === "seal") {
|
|
258
|
+
sealArtifactSigningControlRequest();
|
|
259
|
+
} else if (mode === "outputs") {
|
|
260
|
+
const request = assertArtifactSigningControlRequestContext(
|
|
261
|
+
readArtifactSigningControlRequest(),
|
|
262
|
+
expectedContext(),
|
|
263
|
+
);
|
|
264
|
+
writeGitHubOutputs(artifactSigningControlRequestOutputs(request));
|
|
265
|
+
} else if (mode === "settle") {
|
|
266
|
+
const request = assertArtifactSigningControlRequestContext(
|
|
267
|
+
readArtifactSigningControlRequest(),
|
|
268
|
+
expectedContext(),
|
|
269
|
+
);
|
|
270
|
+
const { receipt, delegation } = settleArtifactSigningControl({ request });
|
|
271
|
+
writeGitHubOutputs({
|
|
272
|
+
"controller-status": receipt.controller.status,
|
|
273
|
+
"controller-receipt-digest": receipt.digest,
|
|
274
|
+
"controller-qualifying": String(receipt.qualifying),
|
|
275
|
+
"delegation-created": String(Boolean(delegation)),
|
|
276
|
+
});
|
|
277
|
+
} else if (mode === "verify") {
|
|
278
|
+
const request = assertArtifactSigningControlRequestContext(
|
|
279
|
+
readArtifactSigningControlRequest(),
|
|
280
|
+
expectedContext(),
|
|
281
|
+
);
|
|
282
|
+
const checked = assertArtifactSigningControllerReceipt({
|
|
283
|
+
request,
|
|
284
|
+
receipt: readArtifactSigningControllerReceipt(),
|
|
285
|
+
delegation: readArtifactSigningDelegation(),
|
|
286
|
+
});
|
|
287
|
+
writeGitHubOutputs({
|
|
288
|
+
...artifactSigningDelegationOutputs(checked.delegation),
|
|
289
|
+
"request-root": checked.receipt.request.root,
|
|
290
|
+
"controller-receipt-digest": checked.receipt.digest,
|
|
291
|
+
"controller-status": checked.receipt.controller.status,
|
|
292
|
+
});
|
|
293
|
+
} else {
|
|
294
|
+
throw new Error(`unsupported artifact signing controller mode: ${mode}`);
|
|
295
|
+
}
|
|
296
|
+
} catch (error) {
|
|
297
|
+
console.error(
|
|
298
|
+
`::error::${String(error?.message || error).replace(/\r?\n/gu, "%0A")}`,
|
|
299
|
+
);
|
|
300
|
+
process.exitCode = 1;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -22,6 +22,14 @@ function optional(value, label) {
|
|
|
22
22
|
return normalized;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function sha256Root(value, label) {
|
|
26
|
+
const normalized = optional(value, label);
|
|
27
|
+
if (normalized && !/^sha256:[0-9a-f]{64}$/u.test(normalized)) {
|
|
28
|
+
throw new Error(`${label} must be a canonical sha256 root`);
|
|
29
|
+
}
|
|
30
|
+
return normalized;
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
function exactSha(value, label) {
|
|
26
34
|
const normalized = required(value, label);
|
|
27
35
|
if (!/^[0-9a-f]{40}$/u.test(normalized))
|
|
@@ -97,8 +105,13 @@ export function validateArtifactSigningDelegation(value) {
|
|
|
97
105
|
requestCount > 0
|
|
98
106
|
? required(value.request?.artifact, "request.artifact")
|
|
99
107
|
: optional(value.request?.artifact, "request.artifact"),
|
|
108
|
+
root: sha256Root(value.request?.root, "request.root"),
|
|
100
109
|
},
|
|
101
110
|
authority: {
|
|
111
|
+
runtimeSha:
|
|
112
|
+
requestCount > 0
|
|
113
|
+
? exactSha(value.authority?.runtimeSha, "authority.runtimeSha")
|
|
114
|
+
: optional(value.authority?.runtimeSha, "authority.runtimeSha"),
|
|
102
115
|
runId:
|
|
103
116
|
requestCount > 0
|
|
104
117
|
? required(value.authority?.runId, "authority.runId")
|
|
@@ -129,15 +142,32 @@ export function validateArtifactSigningDelegation(value) {
|
|
|
129
142
|
value.workingDirectory || ".",
|
|
130
143
|
"workingDirectory",
|
|
131
144
|
),
|
|
145
|
+
controller: {
|
|
146
|
+
mode: optional(value.controller?.mode, "controller.mode"),
|
|
147
|
+
receiptDigest: sha256Root(
|
|
148
|
+
value.controller?.receiptDigest,
|
|
149
|
+
"controller.receiptDigest",
|
|
150
|
+
),
|
|
151
|
+
},
|
|
132
152
|
};
|
|
133
153
|
if (
|
|
134
154
|
requestCount === 0 &&
|
|
135
|
-
(delegation.authority.
|
|
155
|
+
(delegation.authority.runtimeSha ||
|
|
156
|
+
delegation.authority.runId ||
|
|
157
|
+
delegation.authority.resultArtifact)
|
|
136
158
|
) {
|
|
137
159
|
throw new Error(
|
|
138
160
|
"unsigned delegation must not contain authority result coordinates",
|
|
139
161
|
);
|
|
140
162
|
}
|
|
163
|
+
if (
|
|
164
|
+
Boolean(delegation.controller.mode) !==
|
|
165
|
+
Boolean(delegation.controller.receiptDigest)
|
|
166
|
+
) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
"delegation controller mode and receipt digest must be provided together",
|
|
169
|
+
);
|
|
170
|
+
}
|
|
141
171
|
return delegation;
|
|
142
172
|
}
|
|
143
173
|
|
|
@@ -153,12 +183,17 @@ export function createArtifactSigningDelegation({
|
|
|
153
183
|
platformName = process.env.BUILDCHAIN_PLATFORM_NAME,
|
|
154
184
|
requestCount = process.env.BUILDCHAIN_SIGNING_REQUEST_COUNT || "0",
|
|
155
185
|
requestArtifact = process.env.BUILDCHAIN_SIGNING_REQUEST_ARTIFACT || "",
|
|
186
|
+
requestRoot = process.env.BUILDCHAIN_SIGNING_REQUEST_ROOT_DIGEST || "",
|
|
156
187
|
authorityRunId = process.env.BUILDCHAIN_AUTHORITY_RUN_ID || "",
|
|
188
|
+
authorityRuntimeSha = process.env.BUILDCHAIN_AUTHORITY_RUNTIME_SHA || "",
|
|
157
189
|
resultArtifact = process.env.BUILDCHAIN_SIGNING_RESULT_ARTIFACT || "",
|
|
158
190
|
artifactName = process.env.BUILDCHAIN_ARTIFACT_NAME,
|
|
159
191
|
manifestArtifact = process.env.BUILDCHAIN_MANIFEST_ARTIFACT_NAME,
|
|
160
192
|
diagnosticsArtifact = process.env.BUILDCHAIN_DIAGNOSTICS_ARTIFACT_NAME,
|
|
161
193
|
workingDirectory = process.env.BUILDCHAIN_SIGNING_CWD || ".",
|
|
194
|
+
controllerMode = process.env.BUILDCHAIN_SIGNING_CONTROLLER_MODE || "",
|
|
195
|
+
controllerReceiptDigest = process.env
|
|
196
|
+
.BUILDCHAIN_SIGNING_CONTROLLER_RECEIPT_DIGEST || "",
|
|
162
197
|
} = {}) {
|
|
163
198
|
return validateArtifactSigningDelegation({
|
|
164
199
|
schemaVersion: 1,
|
|
@@ -172,10 +207,22 @@ export function createArtifactSigningDelegation({
|
|
|
172
207
|
},
|
|
173
208
|
runtime: { repository: runtimeRepository, sha: runtimeSha },
|
|
174
209
|
platform: { id: platformId, name: platformName },
|
|
175
|
-
request: {
|
|
176
|
-
|
|
210
|
+
request: {
|
|
211
|
+
count: Number(requestCount),
|
|
212
|
+
artifact: requestArtifact,
|
|
213
|
+
root: requestRoot,
|
|
214
|
+
},
|
|
215
|
+
authority: {
|
|
216
|
+
runtimeSha: authorityRuntimeSha,
|
|
217
|
+
runId: authorityRunId,
|
|
218
|
+
resultArtifact,
|
|
219
|
+
},
|
|
177
220
|
artifact: { name: artifactName, manifestArtifact, diagnosticsArtifact },
|
|
178
221
|
workingDirectory,
|
|
222
|
+
controller: {
|
|
223
|
+
mode: controllerMode,
|
|
224
|
+
receiptDigest: controllerReceiptDigest,
|
|
225
|
+
},
|
|
179
226
|
});
|
|
180
227
|
}
|
|
181
228
|
|
|
@@ -205,6 +252,7 @@ export function artifactSigningDelegationOutputs(delegation) {
|
|
|
205
252
|
"request-count": String(value.request.count),
|
|
206
253
|
"request-artifact": value.request.artifact,
|
|
207
254
|
"authority-run-id": value.authority.runId,
|
|
255
|
+
"authority-runtime-sha": value.authority.runtimeSha,
|
|
208
256
|
"result-artifact": value.authority.resultArtifact,
|
|
209
257
|
"artifact-name": value.artifact.name,
|
|
210
258
|
"manifest-artifact-name": value.artifact.manifestArtifact,
|