@docker/actions-toolkit 0.76.0 → 0.77.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/lib/buildkit/buildkit.d.ts +3 -3
- package/lib/buildkit/buildkit.js +67 -117
- package/lib/buildkit/buildkit.js.map +1 -1
- package/lib/buildkit/config.js +7 -14
- package/lib/buildkit/config.js.map +1 -1
- package/lib/buildkit/git.d.ts +1 -1
- package/lib/buildkit/git.js +8 -12
- package/lib/buildkit/git.js.map +1 -1
- package/lib/buildx/bake.d.ts +4 -4
- package/lib/buildx/bake.js +76 -93
- package/lib/buildx/bake.js.map +1 -1
- package/lib/buildx/build.d.ts +5 -5
- package/lib/buildx/build.js +44 -78
- package/lib/buildx/build.js.map +1 -1
- package/lib/buildx/builder.d.ts +2 -2
- package/lib/buildx/builder.js +42 -91
- package/lib/buildx/builder.js.map +1 -1
- package/lib/buildx/buildx.d.ts +3 -3
- package/lib/buildx/buildx.js +212 -274
- package/lib/buildx/buildx.js.map +1 -1
- package/lib/buildx/history.d.ts +2 -2
- package/lib/buildx/history.js +226 -284
- package/lib/buildx/history.js.map +1 -1
- package/lib/buildx/imagetools.d.ts +5 -5
- package/lib/buildx/imagetools.js +67 -92
- package/lib/buildx/imagetools.js.map +1 -1
- package/lib/buildx/install.d.ts +14 -3
- package/lib/buildx/install.js +239 -276
- package/lib/buildx/install.js.map +1 -1
- package/lib/cache.js +88 -138
- package/lib/cache.js.map +1 -1
- package/lib/compose/compose.js +53 -107
- package/lib/compose/compose.js.map +1 -1
- package/lib/compose/install.d.ts +2 -2
- package/lib/compose/install.js +129 -191
- package/lib/compose/install.js.map +1 -1
- package/lib/context.js +10 -50
- package/lib/context.js.map +1 -1
- package/lib/cosign/cosign.js +55 -106
- package/lib/cosign/cosign.js.map +1 -1
- package/lib/cosign/dockerfile.js +1 -4
- package/lib/cosign/dockerfile.js.map +1 -1
- package/lib/cosign/install.d.ts +6 -3
- package/lib/cosign/install.js +183 -261
- package/lib/cosign/install.js.map +1 -1
- package/lib/docker/assets.js +15 -24
- package/lib/docker/assets.js.map +1 -1
- package/lib/docker/docker.d.ts +1 -1
- package/lib/docker/docker.js +112 -182
- package/lib/docker/docker.js.map +1 -1
- package/lib/docker/install.d.ts +3 -3
- package/lib/docker/install.js +543 -617
- package/lib/docker/install.js.map +1 -1
- package/lib/dockerhub.d.ts +1 -1
- package/lib/dockerhub.js +67 -125
- package/lib/dockerhub.js.map +1 -1
- package/lib/exec.js +9 -59
- package/lib/exec.js.map +1 -1
- package/lib/git.d.ts +2 -1
- package/lib/git.js +144 -220
- package/lib/git.js.map +1 -1
- package/lib/github/artifact.d.ts +19 -0
- package/lib/github/artifact.js +49 -0
- package/lib/github/artifact.js.map +1 -0
- package/lib/{github.d.ts → github/github.d.ts} +4 -8
- package/lib/github/github.js +135 -0
- package/lib/github/github.js.map +1 -0
- package/lib/github/summary.d.ts +20 -0
- package/lib/github/summary.js +166 -0
- package/lib/github/summary.js.map +1 -0
- package/lib/index.js +17 -64
- package/lib/index.js.map +1 -1
- package/lib/oci/oci.d.ts +2 -2
- package/lib/oci/oci.js +52 -104
- package/lib/oci/oci.js.map +1 -1
- package/lib/regclient/install.d.ts +2 -2
- package/lib/regclient/install.js +83 -141
- package/lib/regclient/install.js.map +1 -1
- package/lib/regclient/regctl.d.ts +1 -1
- package/lib/regclient/regctl.js +67 -123
- package/lib/regclient/regctl.js.map +1 -1
- package/lib/sigstore/sigstore.d.ts +5 -3
- package/lib/sigstore/sigstore.js +355 -368
- package/lib/sigstore/sigstore.js.map +1 -1
- package/lib/toolkit.d.ts +16 -16
- package/lib/toolkit.js +49 -37
- package/lib/toolkit.js.map +1 -1
- package/lib/types/buildkit/buildkit.js +1 -4
- package/lib/types/buildkit/buildkit.js.map +1 -1
- package/lib/types/buildkit/client.d.ts +2 -2
- package/lib/types/buildkit/client.js +1 -2
- package/lib/types/buildkit/client.js.map +1 -1
- package/lib/types/buildkit/control.d.ts +4 -4
- package/lib/types/buildkit/control.js +1 -2
- package/lib/types/buildkit/control.js.map +1 -1
- package/lib/types/buildkit/git.js +1 -2
- package/lib/types/buildkit/git.js.map +1 -1
- package/lib/types/buildkit/ops.js +1 -2
- package/lib/types/buildkit/ops.js.map +1 -1
- package/lib/types/buildkit/rpc.js +1 -2
- package/lib/types/buildkit/rpc.js.map +1 -1
- package/lib/types/buildx/bake.js +1 -2
- package/lib/types/buildx/bake.js.map +1 -1
- package/lib/types/buildx/build.js +1 -2
- package/lib/types/buildx/build.js.map +1 -1
- package/lib/types/buildx/builder.js +1 -2
- package/lib/types/buildx/builder.js.map +1 -1
- package/lib/types/buildx/buildx.d.ts +1 -1
- package/lib/types/buildx/buildx.js +1 -2
- package/lib/types/buildx/buildx.js.map +1 -1
- package/lib/types/buildx/history.js +1 -2
- package/lib/types/buildx/history.js.map +1 -1
- package/lib/types/buildx/imagetools.d.ts +3 -3
- package/lib/types/buildx/imagetools.js +1 -2
- package/lib/types/buildx/imagetools.js.map +1 -1
- package/lib/types/compose/compose.d.ts +1 -1
- package/lib/types/compose/compose.js +1 -2
- package/lib/types/compose/compose.js.map +1 -1
- package/lib/types/cosign/cosign.d.ts +1 -1
- package/lib/types/cosign/cosign.js +1 -2
- package/lib/types/cosign/cosign.js.map +1 -1
- package/lib/types/docker/docker.js +1 -2
- package/lib/types/docker/docker.js.map +1 -1
- package/lib/types/docker/mediatype.js +3 -6
- package/lib/types/docker/mediatype.js.map +1 -1
- package/lib/types/dockerhub.js +1 -2
- package/lib/types/dockerhub.js.map +1 -1
- package/lib/types/github/artifact.d.ts +26 -0
- package/lib/types/{git.d.ts → github/artifact.js} +3 -3
- package/lib/types/github/artifact.js.map +1 -0
- package/lib/types/{github.d.ts → github/github.d.ts} +4 -23
- package/lib/types/{git.js → github/github.js} +2 -3
- package/lib/types/github/github.js.map +1 -0
- package/lib/types/github/summary.d.ts +29 -0
- package/lib/types/{github.js → github/summary.js} +3 -4
- package/lib/types/github/summary.js.map +1 -0
- package/lib/types/intoto/intoto.js +2 -5
- package/lib/types/intoto/intoto.js.map +1 -1
- package/lib/types/intoto/slsa_provenance/v0.2/provenance.js +1 -4
- package/lib/types/intoto/slsa_provenance/v0.2/provenance.js.map +1 -1
- package/lib/types/oci/config.d.ts +2 -2
- package/lib/types/oci/config.js +1 -2
- package/lib/types/oci/config.js.map +1 -1
- package/lib/types/oci/descriptor.d.ts +1 -1
- package/lib/types/oci/descriptor.js +3 -6
- package/lib/types/oci/descriptor.js.map +1 -1
- package/lib/types/oci/digest.js +1 -2
- package/lib/types/oci/digest.js.map +1 -1
- package/lib/types/oci/index.d.ts +2 -2
- package/lib/types/oci/index.js +1 -2
- package/lib/types/oci/index.js.map +1 -1
- package/lib/types/oci/layout.js +4 -7
- package/lib/types/oci/layout.js.map +1 -1
- package/lib/types/oci/manifest.d.ts +2 -2
- package/lib/types/oci/manifest.js +1 -2
- package/lib/types/oci/manifest.js.map +1 -1
- package/lib/types/oci/mediatype.js +6 -9
- package/lib/types/oci/mediatype.js.map +1 -1
- package/lib/types/oci/oci.d.ts +4 -4
- package/lib/types/oci/oci.js +1 -2
- package/lib/types/oci/oci.js.map +1 -1
- package/lib/types/oci/versioned.js +1 -2
- package/lib/types/oci/versioned.js.map +1 -1
- package/lib/types/regclient/regclient.d.ts +1 -1
- package/lib/types/regclient/regclient.js +1 -2
- package/lib/types/regclient/regclient.js.map +1 -1
- package/lib/types/sigstore/sigstore.d.ts +11 -2
- package/lib/types/sigstore/sigstore.js +4 -7
- package/lib/types/sigstore/sigstore.js.map +1 -1
- package/lib/types/undock/undock.d.ts +1 -1
- package/lib/types/undock/undock.js +1 -2
- package/lib/types/undock/undock.js.map +1 -1
- package/lib/undock/install.d.ts +2 -2
- package/lib/undock/install.js +93 -151
- package/lib/undock/install.js.map +1 -1
- package/lib/undock/undock.js +88 -141
- package/lib/undock/undock.js.map +1 -1
- package/lib/util.js +36 -89
- package/lib/util.js.map +1 -1
- package/package.json +31 -42
- package/lib/github.js +0 -421
- package/lib/github.js.map +0 -1
- package/lib/types/git.js.map +0 -1
- package/lib/types/github.js.map +0 -1
package/lib/sigstore/sigstore.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Copyright 2025 actions-toolkit authors
|
|
4
3
|
*
|
|
@@ -14,389 +13,377 @@
|
|
|
14
13
|
* See the License for the specific language governing permissions and
|
|
15
14
|
* limitations under the License.
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
-
var ar = [];
|
|
37
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
-
return ar;
|
|
39
|
-
};
|
|
40
|
-
return ownKeys(o);
|
|
41
|
-
};
|
|
42
|
-
return function (mod) {
|
|
43
|
-
if (mod && mod.__esModule) return mod;
|
|
44
|
-
var result = {};
|
|
45
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
-
__setModuleDefault(result, mod);
|
|
47
|
-
return result;
|
|
48
|
-
};
|
|
49
|
-
})();
|
|
50
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
51
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
52
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
53
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
54
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
55
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
56
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
60
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
61
|
-
};
|
|
62
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
-
exports.Sigstore = void 0;
|
|
64
|
-
const crypto_1 = require("crypto");
|
|
65
|
-
const fs_1 = __importDefault(require("fs"));
|
|
66
|
-
const path_1 = __importDefault(require("path"));
|
|
67
|
-
const core = __importStar(require("@actions/core"));
|
|
68
|
-
const bundle_1 = require("@sigstore/bundle");
|
|
69
|
-
const sign_1 = require("@sigstore/sign");
|
|
70
|
-
const context_1 = require("../context");
|
|
71
|
-
const cosign_1 = require("../cosign/cosign");
|
|
72
|
-
const exec_1 = require("../exec");
|
|
73
|
-
const github_1 = require("../github");
|
|
74
|
-
const imagetools_1 = require("../buildx/imagetools");
|
|
75
|
-
const intoto_1 = require("../types/intoto/intoto");
|
|
76
|
-
const sigstore_1 = require("../types/sigstore/sigstore");
|
|
77
|
-
class Sigstore {
|
|
16
|
+
import { X509Certificate } from 'crypto';
|
|
17
|
+
import fs from 'fs';
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import * as core from '@actions/core';
|
|
20
|
+
import { bundleFromJSON, bundleToJSON } from '@sigstore/bundle';
|
|
21
|
+
import { CIContextProvider, DSSEBundleBuilder, FulcioSigner, RekorWitness, TSAWitness } from '@sigstore/sign';
|
|
22
|
+
import * as tuf from '@sigstore/tuf';
|
|
23
|
+
import { toSignedEntity, toTrustMaterial, Verifier } from '@sigstore/verify';
|
|
24
|
+
import { Context } from '../context.js';
|
|
25
|
+
import { Cosign } from '../cosign/cosign.js';
|
|
26
|
+
import { Exec } from '../exec.js';
|
|
27
|
+
import { GitHub } from '../github/github.js';
|
|
28
|
+
import { ImageTools } from '../buildx/imagetools.js';
|
|
29
|
+
import { MEDIATYPE_PAYLOAD as INTOTO_MEDIATYPE_PAYLOAD } from '../types/intoto/intoto.js';
|
|
30
|
+
import { FULCIO_URL, REKOR_URL, SEARCH_URL, TSASERVER_URL } from '../types/sigstore/sigstore.js';
|
|
31
|
+
export class Sigstore {
|
|
32
|
+
cosign;
|
|
33
|
+
imageTools;
|
|
78
34
|
constructor(opts) {
|
|
79
|
-
this.cosign =
|
|
80
|
-
this.imageTools =
|
|
35
|
+
this.cosign = opts?.cosign || new Cosign();
|
|
36
|
+
this.imageTools = opts?.imageTools || new ImageTools();
|
|
81
37
|
}
|
|
82
|
-
signAttestationManifests(opts) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
38
|
+
async signAttestationManifests(opts) {
|
|
39
|
+
if (!(await this.cosign.isAvailable())) {
|
|
40
|
+
throw new Error('Cosign is required to sign attestation manifests');
|
|
41
|
+
}
|
|
42
|
+
const result = {};
|
|
43
|
+
try {
|
|
44
|
+
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
45
|
+
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
|
|
86
46
|
}
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
47
|
+
const endpoints = this.signingEndpoints(opts.noTransparencyLog);
|
|
48
|
+
core.info(`Using Sigstore signing endpoint: ${endpoints.fulcioURL}`);
|
|
49
|
+
const noTransparencyLog = Sigstore.noTransparencyLog(opts.noTransparencyLog);
|
|
50
|
+
const cosignExtraArgs = [];
|
|
51
|
+
if (await this.cosign.versionSatisfies('>=3.0.4')) {
|
|
52
|
+
await core.group(`Creating Sigstore protobuf signing config`, async () => {
|
|
53
|
+
const signingConfig = Context.tmpName({
|
|
54
|
+
template: 'signing-config-XXXXXX.json',
|
|
55
|
+
tmpdir: Context.tmpDir()
|
|
56
|
+
});
|
|
57
|
+
// prettier-ignore
|
|
58
|
+
const createConfigArgs = [
|
|
59
|
+
'signing-config',
|
|
60
|
+
'create',
|
|
61
|
+
'--with-default-services=true',
|
|
62
|
+
`--out=${signingConfig}`
|
|
63
|
+
];
|
|
64
|
+
if (noTransparencyLog) {
|
|
65
|
+
createConfigArgs.push('--no-default-rekor=true');
|
|
66
|
+
}
|
|
67
|
+
await Exec.exec('cosign', createConfigArgs, {
|
|
68
|
+
env: Object.assign({}, process.env, {
|
|
69
|
+
COSIGN_EXPERIMENTAL: '1'
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
core.info(JSON.stringify(JSON.parse(fs.readFileSync(signingConfig, { encoding: 'utf-8' })), null, 2));
|
|
73
|
+
cosignExtraArgs.push(`--signing-config=${signingConfig}`);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
cosignExtraArgs.push('--use-signing-config');
|
|
78
|
+
if (noTransparencyLog) {
|
|
79
|
+
cosignExtraArgs.push('--tlog-upload=false');
|
|
91
80
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const signingConfig = context_1.Context.tmpName({
|
|
99
|
-
template: 'signing-config-XXXXXX.json',
|
|
100
|
-
tmpdir: context_1.Context.tmpDir()
|
|
101
|
-
});
|
|
81
|
+
}
|
|
82
|
+
for (const imageName of opts.imageNames) {
|
|
83
|
+
const attestationDigests = await this.imageTools.attestationDigests(`${imageName}@${opts.imageDigest}`);
|
|
84
|
+
for (const attestationDigest of attestationDigests) {
|
|
85
|
+
const attestationRef = `${imageName}@${attestationDigest}`;
|
|
86
|
+
await core.group(`Signing attestation manifest ${attestationRef}`, async () => {
|
|
102
87
|
// prettier-ignore
|
|
103
|
-
const
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'--
|
|
107
|
-
|
|
88
|
+
const cosignArgs = [
|
|
89
|
+
'sign',
|
|
90
|
+
'--yes',
|
|
91
|
+
'--oidc-provider', 'github-actions',
|
|
92
|
+
'--registry-referrers-mode', 'oci-1-1',
|
|
93
|
+
'--new-bundle-format',
|
|
94
|
+
...cosignExtraArgs
|
|
108
95
|
];
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
96
|
+
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
|
|
97
|
+
const execRes = await Exec.getExecOutput('cosign', ['--verbose', ...cosignArgs, attestationRef], {
|
|
98
|
+
ignoreReturnCode: true,
|
|
99
|
+
silent: true,
|
|
113
100
|
env: Object.assign({}, process.env, {
|
|
114
101
|
COSIGN_EXPERIMENTAL: '1'
|
|
115
102
|
})
|
|
116
103
|
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
cosignExtraArgs.push('--use-signing-config');
|
|
123
|
-
if (noTransparencyLog) {
|
|
124
|
-
cosignExtraArgs.push('--tlog-upload=false');
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
for (const imageName of opts.imageNames) {
|
|
128
|
-
const attestationDigests = yield this.imageTools.attestationDigests(`${imageName}@${opts.imageDigest}`);
|
|
129
|
-
for (const attestationDigest of attestationDigests) {
|
|
130
|
-
const attestationRef = `${imageName}@${attestationDigest}`;
|
|
131
|
-
yield core.group(`Signing attestation manifest ${attestationRef}`, () => __awaiter(this, void 0, void 0, function* () {
|
|
132
|
-
var _a;
|
|
133
|
-
// prettier-ignore
|
|
134
|
-
const cosignArgs = [
|
|
135
|
-
'sign',
|
|
136
|
-
'--yes',
|
|
137
|
-
'--oidc-provider', 'github-actions',
|
|
138
|
-
'--registry-referrers-mode', 'oci-1-1',
|
|
139
|
-
'--new-bundle-format',
|
|
140
|
-
...cosignExtraArgs
|
|
141
|
-
];
|
|
142
|
-
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
|
|
143
|
-
const execRes = yield exec_1.Exec.getExecOutput('cosign', ['--verbose', ...cosignArgs, attestationRef], {
|
|
144
|
-
ignoreReturnCode: true,
|
|
145
|
-
silent: true,
|
|
146
|
-
env: Object.assign({}, process.env, {
|
|
147
|
-
COSIGN_EXPERIMENTAL: '1'
|
|
148
|
-
})
|
|
149
|
-
});
|
|
150
|
-
const signResult = cosign_1.Cosign.parseCommandOutput(execRes.stderr.trim());
|
|
151
|
-
if (execRes.exitCode != 0) {
|
|
152
|
-
if (signResult.errors && signResult.errors.length > 0) {
|
|
153
|
-
const errorMessages = signResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
|
|
154
|
-
throw new Error(`Cosign sign command failed with errors:\n${errorMessages}`);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
// prettier-ignore
|
|
158
|
-
throw new Error(`Cosign sign command failed with: ${(_a = execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop()) !== null && _a !== void 0 ? _a : 'unknown error'}`);
|
|
159
|
-
}
|
|
104
|
+
const signResult = Cosign.parseCommandOutput(execRes.stderr.trim());
|
|
105
|
+
if (execRes.exitCode != 0) {
|
|
106
|
+
if (signResult.errors && signResult.errors.length > 0) {
|
|
107
|
+
const errorMessages = signResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
|
|
108
|
+
throw new Error(`Cosign sign command failed with errors:\n${errorMessages}`);
|
|
160
109
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
110
|
+
else {
|
|
111
|
+
// prettier-ignore
|
|
112
|
+
throw new Error(`Cosign sign command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
|
|
164
113
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
verifySignedManifests(signedManifestsResult, opts) {
|
|
178
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
179
|
-
const result = {};
|
|
180
|
-
for (const [attestationRef, signedRes] of Object.entries(signedManifestsResult)) {
|
|
181
|
-
yield core.group(`Verifying signature of ${attestationRef}`, () => __awaiter(this, void 0, void 0, function* () {
|
|
182
|
-
const verifyResult = yield this.verifyImageAttestation(attestationRef, {
|
|
183
|
-
certificateIdentityRegexp: opts.certificateIdentityRegexp,
|
|
184
|
-
noTransparencyLog: opts.noTransparencyLog || !signedRes.tlogID,
|
|
185
|
-
retryOnManifestUnknown: opts.retryOnManifestUnknown
|
|
114
|
+
}
|
|
115
|
+
const parsedBundle = Sigstore.parseBundle(bundleFromJSON(signResult.bundle));
|
|
116
|
+
if (parsedBundle.tlogID) {
|
|
117
|
+
core.info(`Uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${parsedBundle.tlogID}`);
|
|
118
|
+
}
|
|
119
|
+
core.info(`Signature manifest pushed: https://oci.dag.dev/?referrers=${attestationRef}`);
|
|
120
|
+
result[attestationRef] = {
|
|
121
|
+
...parsedBundle,
|
|
122
|
+
imageName: imageName
|
|
123
|
+
};
|
|
186
124
|
});
|
|
187
|
-
|
|
188
|
-
result[attestationRef] = verifyResult;
|
|
189
|
-
}));
|
|
125
|
+
}
|
|
190
126
|
}
|
|
191
|
-
|
|
192
|
-
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
throw new Error(`Signing BuildKit attestation manifests failed: ${err.message}`);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
193
132
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const verifyResult = yield this.verifyImageAttestation(attestationRef, opts);
|
|
205
|
-
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${imageName}@${verifyResult.signatureManifestDigest}`);
|
|
133
|
+
async verifySignedManifests(signedManifestsResult, opts) {
|
|
134
|
+
const result = {};
|
|
135
|
+
for (const [attestationRef, signedRes] of Object.entries(signedManifestsResult)) {
|
|
136
|
+
await core.group(`Verifying signature of ${attestationRef}`, async () => {
|
|
137
|
+
const verifyResult = await this.verifyImageAttestation(attestationRef, {
|
|
138
|
+
certificateIdentityRegexp: opts.certificateIdentityRegexp,
|
|
139
|
+
noTransparencyLog: opts.noTransparencyLog || !signedRes.tlogID,
|
|
140
|
+
retryOnManifestUnknown: opts.retryOnManifestUnknown
|
|
141
|
+
});
|
|
142
|
+
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${signedRes.imageName}@${verifyResult.signatureManifestDigest}`);
|
|
206
143
|
result[attestationRef] = verifyResult;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
210
147
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
148
|
+
async verifyImageAttestations(image, opts) {
|
|
149
|
+
const result = {};
|
|
150
|
+
const attestationDigests = await this.imageTools.attestationDigests(image, opts.platform);
|
|
151
|
+
if (attestationDigests.length === 0) {
|
|
152
|
+
throw new Error(`No attestation manifests found for ${image}`);
|
|
153
|
+
}
|
|
154
|
+
const imageName = image.split(':', 1)[0];
|
|
155
|
+
for (const attestationDigest of attestationDigests) {
|
|
156
|
+
const attestationRef = `${imageName}@${attestationDigest}`;
|
|
157
|
+
const verifyResult = await this.verifyImageAttestation(attestationRef, opts);
|
|
158
|
+
core.info(`Signature manifest verified: https://oci.dag.dev/?image=${imageName}@${verifyResult.signatureManifestDigest}`);
|
|
159
|
+
result[attestationRef] = verifyResult;
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
async verifyImageAttestation(attestationRef, opts) {
|
|
164
|
+
if (!(await this.cosign.isAvailable())) {
|
|
165
|
+
throw new Error('Cosign is required to verify signed manifests');
|
|
166
|
+
}
|
|
167
|
+
// prettier-ignore
|
|
168
|
+
const cosignArgs = [
|
|
169
|
+
'verify',
|
|
170
|
+
'--experimental-oci11',
|
|
171
|
+
'--new-bundle-format',
|
|
172
|
+
'--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com',
|
|
173
|
+
'--certificate-identity-regexp', opts.certificateIdentityRegexp
|
|
174
|
+
];
|
|
175
|
+
if (opts.noTransparencyLog) {
|
|
176
|
+
// skip tlog verification but still verify the signed timestamp
|
|
177
|
+
cosignArgs.push('--use-signed-timestamps', '--insecure-ignore-tlog');
|
|
178
|
+
}
|
|
179
|
+
if (!opts.retryOnManifestUnknown) {
|
|
180
|
+
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
|
|
181
|
+
const execRes = await Exec.getExecOutput('cosign', ['--verbose', ...cosignArgs, attestationRef], {
|
|
182
|
+
ignoreReturnCode: true,
|
|
183
|
+
silent: true,
|
|
184
|
+
env: Object.assign({}, process.env, {
|
|
185
|
+
COSIGN_EXPERIMENTAL: '1'
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
if (execRes.exitCode !== 0) {
|
|
189
|
+
// prettier-ignore
|
|
190
|
+
throw new Error(`Cosign verify command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
|
|
228
191
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
192
|
+
const verifyResult = Cosign.parseCommandOutput(execRes.stderr.trim());
|
|
193
|
+
return {
|
|
194
|
+
cosignArgs: cosignArgs,
|
|
195
|
+
signatureManifestDigest: verifyResult.signatureManifestDigest
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const retries = 15;
|
|
199
|
+
let lastError;
|
|
200
|
+
core.info(`[command]cosign ${[...cosignArgs, attestationRef].join(' ')}`);
|
|
201
|
+
for (let attempt = 0; attempt < retries; attempt++) {
|
|
202
|
+
const execRes = await Exec.getExecOutput('cosign', ['--verbose', ...cosignArgs, attestationRef], {
|
|
203
|
+
ignoreReturnCode: true,
|
|
204
|
+
silent: true,
|
|
205
|
+
env: Object.assign({}, process.env, {
|
|
206
|
+
COSIGN_EXPERIMENTAL: '1'
|
|
207
|
+
})
|
|
208
|
+
});
|
|
209
|
+
const verifyResult = Cosign.parseCommandOutput(execRes.stderr.trim());
|
|
210
|
+
if (execRes.exitCode === 0) {
|
|
243
211
|
return {
|
|
244
212
|
cosignArgs: cosignArgs,
|
|
245
213
|
signatureManifestDigest: verifyResult.signatureManifestDigest
|
|
246
214
|
};
|
|
247
215
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
env: Object.assign({}, process.env, {
|
|
256
|
-
COSIGN_EXPERIMENTAL: '1'
|
|
257
|
-
})
|
|
258
|
-
});
|
|
259
|
-
const verifyResult = cosign_1.Cosign.parseCommandOutput(execRes.stderr.trim());
|
|
260
|
-
if (execRes.exitCode === 0) {
|
|
261
|
-
return {
|
|
262
|
-
cosignArgs: cosignArgs,
|
|
263
|
-
signatureManifestDigest: verifyResult.signatureManifestDigest
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
if (verifyResult.errors && verifyResult.errors.length > 0) {
|
|
268
|
-
const errorMessages = verifyResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
|
|
269
|
-
lastError = new Error(`Cosign verify command failed with errors:\n${errorMessages}`);
|
|
270
|
-
if (verifyResult.errors.some(e => e.code === 'MANIFEST_UNKNOWN')) {
|
|
271
|
-
core.info(`Cosign verify command failed with MANIFEST_UNKNOWN, retrying attempt ${attempt + 1}/${retries}...\n${errorMessages}`);
|
|
272
|
-
yield new Promise(res => setTimeout(res, Math.pow(2, attempt) * 100));
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
throw lastError;
|
|
276
|
-
}
|
|
216
|
+
else {
|
|
217
|
+
if (verifyResult.errors && verifyResult.errors.length > 0) {
|
|
218
|
+
const errorMessages = verifyResult.errors.map(e => `- [${e.code}] ${e.message} : ${e.detail}`).join('\n');
|
|
219
|
+
lastError = new Error(`Cosign verify command failed with errors:\n${errorMessages}`);
|
|
220
|
+
if (verifyResult.errors.some(e => e.code === 'MANIFEST_UNKNOWN')) {
|
|
221
|
+
core.info(`Cosign verify command failed with MANIFEST_UNKNOWN, retrying attempt ${attempt + 1}/${retries}...\n${errorMessages}`);
|
|
222
|
+
await new Promise(res => setTimeout(res, Math.pow(2, attempt) * 100));
|
|
277
223
|
}
|
|
278
224
|
else {
|
|
279
|
-
|
|
280
|
-
throw new Error(`Cosign verify command failed with: ${(_b = execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop()) !== null && _b !== void 0 ? _b : 'unknown error'}`);
|
|
225
|
+
throw lastError;
|
|
281
226
|
}
|
|
282
227
|
}
|
|
228
|
+
else {
|
|
229
|
+
// prettier-ignore
|
|
230
|
+
throw new Error(`Cosign verify command failed with: ${execRes.stderr.trim().split(/\r?\n/).filter(line => line.length > 0).pop() ?? 'unknown error'}`);
|
|
231
|
+
}
|
|
283
232
|
}
|
|
284
|
-
|
|
285
|
-
|
|
233
|
+
}
|
|
234
|
+
throw lastError;
|
|
286
235
|
}
|
|
287
|
-
signProvenanceBlobs(opts) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
|
|
293
|
-
}
|
|
294
|
-
const endpoints = this.signingEndpoints(opts.noTransparencyLog);
|
|
295
|
-
core.info(`Using Sigstore signing endpoint: ${endpoints.fulcioURL}`);
|
|
296
|
-
const provenanceBlobs = Sigstore.getProvenanceBlobs(opts);
|
|
297
|
-
for (const p of Object.keys(provenanceBlobs)) {
|
|
298
|
-
yield core.group(`Signing ${p}`, () => __awaiter(this, void 0, void 0, function* () {
|
|
299
|
-
var _a;
|
|
300
|
-
const blob = provenanceBlobs[p];
|
|
301
|
-
const bundlePath = path_1.default.join(path_1.default.dirname(p), `${(_a = opts.name) !== null && _a !== void 0 ? _a : 'provenance'}.sigstore.json`);
|
|
302
|
-
const subjects = Sigstore.getProvenanceSubjects(blob);
|
|
303
|
-
if (subjects.length === 0) {
|
|
304
|
-
core.warning(`No subjects found in provenance ${p}, skip signing.`);
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
const bundle = yield Sigstore.signPayload({
|
|
308
|
-
data: blob,
|
|
309
|
-
type: intoto_1.MEDIATYPE_PAYLOAD
|
|
310
|
-
}, endpoints);
|
|
311
|
-
const parsedBundle = Sigstore.parseBundle(bundle);
|
|
312
|
-
core.info(`Provenance blob signed for:`);
|
|
313
|
-
for (const subject of subjects) {
|
|
314
|
-
const [digestAlg, digestValue] = Object.entries(subject.digest)[0] || [];
|
|
315
|
-
core.info(` - ${subject.name} (${digestAlg}:${digestValue})`);
|
|
316
|
-
}
|
|
317
|
-
if (parsedBundle.tlogID) {
|
|
318
|
-
core.info(`Attestation signature uploaded to Rekor transparency log: ${sigstore_1.SEARCH_URL}?logIndex=${parsedBundle.tlogID}`);
|
|
319
|
-
}
|
|
320
|
-
core.info(`Writing Sigstore bundle to: ${bundlePath}`);
|
|
321
|
-
fs_1.default.writeFileSync(bundlePath, JSON.stringify(parsedBundle.payload, null, 2), {
|
|
322
|
-
encoding: 'utf-8'
|
|
323
|
-
});
|
|
324
|
-
result[p] = Object.assign(Object.assign({}, parsedBundle), { bundlePath: bundlePath, subjects: subjects });
|
|
325
|
-
}));
|
|
326
|
-
}
|
|
236
|
+
async signProvenanceBlobs(opts) {
|
|
237
|
+
const result = {};
|
|
238
|
+
try {
|
|
239
|
+
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
|
|
240
|
+
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
|
|
327
241
|
}
|
|
328
|
-
|
|
329
|
-
|
|
242
|
+
const endpoints = this.signingEndpoints(opts.noTransparencyLog);
|
|
243
|
+
core.info(`Using Sigstore signing endpoint: ${endpoints.fulcioURL}`);
|
|
244
|
+
const provenanceBlobs = Sigstore.getProvenanceBlobs(opts);
|
|
245
|
+
for (const p of Object.keys(provenanceBlobs)) {
|
|
246
|
+
await core.group(`Signing ${p}`, async () => {
|
|
247
|
+
const blob = provenanceBlobs[p];
|
|
248
|
+
const bundlePath = path.join(path.dirname(p), `${opts.name ?? 'provenance'}.sigstore.json`);
|
|
249
|
+
const subjects = Sigstore.getProvenanceSubjects(blob);
|
|
250
|
+
if (subjects.length === 0) {
|
|
251
|
+
core.warning(`No subjects found in provenance ${p}, skip signing.`);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const bundle = await Sigstore.signPayload({
|
|
255
|
+
data: blob,
|
|
256
|
+
type: INTOTO_MEDIATYPE_PAYLOAD
|
|
257
|
+
}, endpoints);
|
|
258
|
+
const parsedBundle = Sigstore.parseBundle(bundle);
|
|
259
|
+
core.info(`Provenance blob signed for:`);
|
|
260
|
+
for (const subject of subjects) {
|
|
261
|
+
const [digestAlg, digestValue] = Object.entries(subject.digest)[0] || [];
|
|
262
|
+
core.info(` - ${subject.name} (${digestAlg}:${digestValue})`);
|
|
263
|
+
}
|
|
264
|
+
if (parsedBundle.tlogID) {
|
|
265
|
+
core.info(`Attestation signature uploaded to Rekor transparency log: ${SEARCH_URL}?logIndex=${parsedBundle.tlogID}`);
|
|
266
|
+
}
|
|
267
|
+
core.info(`Writing Sigstore bundle to: ${bundlePath}`);
|
|
268
|
+
fs.writeFileSync(bundlePath, JSON.stringify(parsedBundle.payload, null, 2), {
|
|
269
|
+
encoding: 'utf-8'
|
|
270
|
+
});
|
|
271
|
+
result[p] = {
|
|
272
|
+
...parsedBundle,
|
|
273
|
+
bundlePath: bundlePath,
|
|
274
|
+
subjects: subjects
|
|
275
|
+
};
|
|
276
|
+
});
|
|
330
277
|
}
|
|
331
|
-
|
|
332
|
-
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
throw new Error(`Signing BuildKit provenance blobs failed: ${err.message}`);
|
|
281
|
+
}
|
|
282
|
+
return result;
|
|
333
283
|
}
|
|
334
|
-
verifySignedArtifacts(signedArtifactsResult, opts) {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
if
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
throw new Error(execRes.stderr);
|
|
362
|
-
}
|
|
363
|
-
result[artifactPath] = {
|
|
364
|
-
bundlePath: signedRes.bundlePath,
|
|
365
|
-
cosignArgs: cosignArgs
|
|
366
|
-
};
|
|
284
|
+
async verifySignedArtifacts(signedArtifactsResult, opts) {
|
|
285
|
+
const result = {};
|
|
286
|
+
if (!(await this.cosign.isAvailable())) {
|
|
287
|
+
throw new Error('Cosign is required to verify signed artifacts');
|
|
288
|
+
}
|
|
289
|
+
for (const [provenancePath, signedRes] of Object.entries(signedArtifactsResult)) {
|
|
290
|
+
const baseDir = path.dirname(provenancePath);
|
|
291
|
+
await core.group(`Verifying signature bundle ${signedRes.bundlePath}`, async () => {
|
|
292
|
+
for (const subject of signedRes.subjects) {
|
|
293
|
+
const artifactPath = path.join(baseDir, subject.name);
|
|
294
|
+
core.info(`Verifying signed artifact ${artifactPath}`);
|
|
295
|
+
// prettier-ignore
|
|
296
|
+
const cosignArgs = [
|
|
297
|
+
'verify-blob-attestation',
|
|
298
|
+
'--new-bundle-format',
|
|
299
|
+
'--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com',
|
|
300
|
+
'--certificate-identity-regexp', opts.certificateIdentityRegexp
|
|
301
|
+
];
|
|
302
|
+
if (opts.noTransparencyLog || !signedRes.tlogID) {
|
|
303
|
+
// if there is no tlog entry, we skip tlog verification but still verify the signed timestamp
|
|
304
|
+
cosignArgs.push('--use-signed-timestamps', '--insecure-ignore-tlog');
|
|
305
|
+
}
|
|
306
|
+
const execRes = await Exec.getExecOutput('cosign', [...cosignArgs, '--bundle', signedRes.bundlePath, artifactPath], {
|
|
307
|
+
ignoreReturnCode: true
|
|
308
|
+
});
|
|
309
|
+
if (execRes.stderr.length > 0 && execRes.exitCode != 0) {
|
|
310
|
+
throw new Error(execRes.stderr);
|
|
367
311
|
}
|
|
368
|
-
|
|
312
|
+
result[artifactPath] = {
|
|
313
|
+
bundlePath: signedRes.bundlePath,
|
|
314
|
+
cosignArgs: cosignArgs
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
async verifyArtifact(artifactPath, bundlePath, opts) {
|
|
322
|
+
core.info(`Verifying keyless verification bundle signature`);
|
|
323
|
+
const parsedBundle = JSON.parse(fs.readFileSync(bundlePath, 'utf-8'));
|
|
324
|
+
const bundle = bundleFromJSON(parsedBundle);
|
|
325
|
+
core.info(`Fetching Sigstore TUF trusted root metadata`);
|
|
326
|
+
const trustedRoot = await tuf.getTrustedRoot();
|
|
327
|
+
const trustMaterial = toTrustMaterial(trustedRoot);
|
|
328
|
+
try {
|
|
329
|
+
core.info(`Verifying artifact signature`);
|
|
330
|
+
const signedEntity = toSignedEntity(bundle, fs.readFileSync(artifactPath));
|
|
331
|
+
const signingCert = Sigstore.parseCertificate(bundle);
|
|
332
|
+
// collect transparency log ID if available
|
|
333
|
+
const tlogEntries = bundle.verificationMaterial.tlogEntries;
|
|
334
|
+
const tlogID = tlogEntries.length > 0 ? tlogEntries[0].logIndex : undefined;
|
|
335
|
+
// TODO: remove when subjectAlternativeName check with regex is supported: https://github.com/sigstore/sigstore-js/pull/1556
|
|
336
|
+
if (opts?.subjectAlternativeName && opts?.subjectAlternativeName instanceof RegExp) {
|
|
337
|
+
const subjectAltName = signingCert.subjectAltName?.replace(/^uri:/i, '');
|
|
338
|
+
if (!subjectAltName) {
|
|
339
|
+
throw new Error('Signing certificate does not contain subjectAltName');
|
|
340
|
+
}
|
|
341
|
+
else if (!subjectAltName.match(opts.subjectAlternativeName)) {
|
|
342
|
+
throw new Error(`Signing certificate subjectAlternativeName "${subjectAltName}" does not match expected pattern`);
|
|
343
|
+
}
|
|
369
344
|
}
|
|
370
|
-
|
|
371
|
-
|
|
345
|
+
const verifier = new Verifier(trustMaterial);
|
|
346
|
+
const signer = verifier.verify(signedEntity, {
|
|
347
|
+
subjectAlternativeName: opts?.subjectAlternativeName && typeof opts.subjectAlternativeName === 'string' ? opts.subjectAlternativeName : undefined,
|
|
348
|
+
extensions: opts?.issuer ? { issuer: opts.issuer } : undefined
|
|
349
|
+
});
|
|
350
|
+
core.debug(`Sigstore.verifyArtifact signer: ${JSON.stringify(signer)}`);
|
|
351
|
+
return {
|
|
352
|
+
payload: parsedBundle,
|
|
353
|
+
certificate: signingCert.toString(),
|
|
354
|
+
tlogID: tlogID
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
throw new Error(`Failed to verify artifact signature: ${err}`);
|
|
359
|
+
}
|
|
372
360
|
}
|
|
373
361
|
signingEndpoints(noTransparencyLog) {
|
|
374
362
|
noTransparencyLog = Sigstore.noTransparencyLog(noTransparencyLog);
|
|
375
363
|
core.info(`Upload to transparency log: ${noTransparencyLog ? 'disabled' : 'enabled'}`);
|
|
376
364
|
return {
|
|
377
|
-
fulcioURL:
|
|
378
|
-
rekorURL: noTransparencyLog ? undefined :
|
|
379
|
-
tsaServerURL:
|
|
365
|
+
fulcioURL: FULCIO_URL,
|
|
366
|
+
rekorURL: noTransparencyLog ? undefined : REKOR_URL,
|
|
367
|
+
tsaServerURL: TSASERVER_URL
|
|
380
368
|
};
|
|
381
369
|
}
|
|
382
370
|
static noTransparencyLog(noTransparencyLog) {
|
|
383
|
-
|
|
384
|
-
return noTransparencyLog !== null && noTransparencyLog !== void 0 ? noTransparencyLog : (_a = github_1.GitHub.context.payload.repository) === null || _a === void 0 ? void 0 : _a.private;
|
|
371
|
+
return noTransparencyLog ?? GitHub.context.payload.repository?.private;
|
|
385
372
|
}
|
|
386
373
|
static getProvenanceBlobs(opts) {
|
|
387
374
|
// For single platform build
|
|
388
|
-
const singleProvenance =
|
|
389
|
-
if (
|
|
390
|
-
return { [singleProvenance]:
|
|
375
|
+
const singleProvenance = path.join(opts.localExportDir, 'provenance.json');
|
|
376
|
+
if (fs.existsSync(singleProvenance)) {
|
|
377
|
+
return { [singleProvenance]: fs.readFileSync(singleProvenance) };
|
|
391
378
|
}
|
|
392
379
|
// For multi-platform build
|
|
393
|
-
const dirents =
|
|
380
|
+
const dirents = fs.readdirSync(opts.localExportDir, { withFileTypes: true });
|
|
394
381
|
const platformFolders = dirents.filter(dirent => dirent.isDirectory());
|
|
395
|
-
if (platformFolders.length > 0 && platformFolders.length === dirents.length && platformFolders.every(platformFolder =>
|
|
382
|
+
if (platformFolders.length > 0 && platformFolders.length === dirents.length && platformFolders.every(platformFolder => fs.existsSync(path.join(opts.localExportDir, platformFolder.name, 'provenance.json')))) {
|
|
396
383
|
const result = {};
|
|
397
384
|
for (const platformFolder of platformFolders) {
|
|
398
|
-
const p =
|
|
399
|
-
result[p] =
|
|
385
|
+
const p = path.join(opts.localExportDir, platformFolder.name, 'provenance.json');
|
|
386
|
+
result[p] = fs.readFileSync(p);
|
|
400
387
|
}
|
|
401
388
|
return result;
|
|
402
389
|
}
|
|
@@ -409,34 +396,43 @@ class Sigstore {
|
|
|
409
396
|
digest: s.digest
|
|
410
397
|
}));
|
|
411
398
|
}
|
|
412
|
-
static signPayload(artifact, endpoints, timeout, retries) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
399
|
+
static async signPayload(artifact, endpoints, timeout, retries) {
|
|
400
|
+
const witnesses = [];
|
|
401
|
+
const signer = new FulcioSigner({
|
|
402
|
+
identityProvider: new CIContextProvider('sigstore'),
|
|
403
|
+
fulcioBaseURL: endpoints.fulcioURL,
|
|
404
|
+
timeout: timeout,
|
|
405
|
+
retry: retries
|
|
406
|
+
});
|
|
407
|
+
if (endpoints.rekorURL) {
|
|
408
|
+
witnesses.push(new RekorWitness({
|
|
409
|
+
rekorBaseURL: endpoints.rekorURL,
|
|
410
|
+
fetchOnConflict: true,
|
|
418
411
|
timeout: timeout,
|
|
419
412
|
retry: retries
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
witnesses.push(new sign_1.TSAWitness({
|
|
431
|
-
tsaBaseURL: endpoints.tsaServerURL,
|
|
432
|
-
timeout: timeout,
|
|
433
|
-
retry: retries
|
|
434
|
-
}));
|
|
435
|
-
}
|
|
436
|
-
return new sign_1.DSSEBundleBuilder({ signer, witnesses }).create(artifact);
|
|
437
|
-
});
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
if (endpoints.tsaServerURL) {
|
|
416
|
+
witnesses.push(new TSAWitness({
|
|
417
|
+
tsaBaseURL: endpoints.tsaServerURL,
|
|
418
|
+
timeout: timeout,
|
|
419
|
+
retry: retries
|
|
420
|
+
}));
|
|
421
|
+
}
|
|
422
|
+
return new DSSEBundleBuilder({ signer, witnesses }).create(artifact);
|
|
438
423
|
}
|
|
439
424
|
static parseBundle(bundle) {
|
|
425
|
+
const signingCert = Sigstore.parseCertificate(bundle);
|
|
426
|
+
// collect transparency log ID if available
|
|
427
|
+
const tlogEntries = bundle.verificationMaterial.tlogEntries;
|
|
428
|
+
const tlogID = tlogEntries.length > 0 ? tlogEntries[0].logIndex : undefined;
|
|
429
|
+
return {
|
|
430
|
+
payload: bundleToJSON(bundle),
|
|
431
|
+
certificate: signingCert.toString(),
|
|
432
|
+
tlogID: tlogID
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
static parseCertificate(bundle) {
|
|
440
436
|
let certBytes;
|
|
441
437
|
switch (bundle.verificationMaterial.content.$case) {
|
|
442
438
|
case 'x509CertificateChain':
|
|
@@ -448,16 +444,7 @@ class Sigstore {
|
|
|
448
444
|
default:
|
|
449
445
|
throw new Error('Bundle must contain an x509 certificate');
|
|
450
446
|
}
|
|
451
|
-
|
|
452
|
-
// collect transparency log ID if available
|
|
453
|
-
const tlogEntries = bundle.verificationMaterial.tlogEntries;
|
|
454
|
-
const tlogID = tlogEntries.length > 0 ? tlogEntries[0].logIndex : undefined;
|
|
455
|
-
return {
|
|
456
|
-
payload: (0, bundle_1.bundleToJSON)(bundle),
|
|
457
|
-
certificate: signingCert.toString(),
|
|
458
|
-
tlogID: tlogID
|
|
459
|
-
};
|
|
447
|
+
return new X509Certificate(certBytes);
|
|
460
448
|
}
|
|
461
449
|
}
|
|
462
|
-
exports.Sigstore = Sigstore;
|
|
463
450
|
//# sourceMappingURL=sigstore.js.map
|