From da04dbc394e82493cf6fa9665500f13e24e60e61 Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 18 May 2026 10:37:34 +0200 Subject: [PATCH 1/3] sigstore: use pinned trusted root Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- package.json | 2 +- src/sigstore/sigstore.ts | 15 ++++ src/sigstore/trusted_root.json | 126 +++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/sigstore/trusted_root.json diff --git a/package.json b/package.json index ed611fbc..8eb549f3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Toolkit for Docker (GitHub) Actions", "type": "module", "scripts": { - "build": "tsc", + "build": "tsc && node -e \"require('fs').copyFileSync('src/sigstore/trusted_root.json', 'lib/sigstore/trusted_root.json')\"", "lint": "eslint --max-warnings=0 .", "format": "eslint --fix .", "test": "vitest run -c vitest.config.ts", diff --git a/src/sigstore/sigstore.ts b/src/sigstore/sigstore.ts index 895cb5b0..3de0a8db 100644 --- a/src/sigstore/sigstore.ts +++ b/src/sigstore/sigstore.ts @@ -17,6 +17,7 @@ import {X509Certificate} from 'crypto'; import fs from 'fs'; import path from 'path'; +import {fileURLToPath} from 'url'; import * as core from '@actions/core'; import {bundleFromJSON, bundleToJSON, SerializedBundle} from '@sigstore/bundle'; @@ -53,17 +54,21 @@ import { export interface SigstoreOpts { cosign?: Cosign; imageTools?: ImageTools; + trustedRootPath?: string; } const COSIGN_PREDICATE_SLSA_PROVENANCE_V1 = 'slsaprovenance1'; +const DEFAULT_TRUSTED_ROOT_PATH = path.join(path.dirname(fileURLToPath(import.meta.url)), 'trusted_root.json'); export class Sigstore { private readonly cosign: Cosign; private readonly imageTools: ImageTools; + private readonly trustedRootPath: string; constructor(opts?: SigstoreOpts) { this.cosign = opts?.cosign || new Cosign(); this.imageTools = opts?.imageTools || new ImageTools(); + this.trustedRootPath = opts?.trustedRootPath || DEFAULT_TRUSTED_ROOT_PATH; } public async signAttestationManifests(opts: SignAttestationManifestsOpts): Promise> { @@ -130,6 +135,7 @@ export class Sigstore { '--oidc-provider', 'github-actions', '--registry-referrers-mode', 'oci-1-1', '--new-bundle-format', + ...this.trustedRootArgs(), ...cosignExtraArgs ]; core.info(`[command]${this.cosign.binPath} ${[...cosignArgs, attestationRef].join(' ')}`); @@ -220,6 +226,7 @@ export class Sigstore { 'verify', '--experimental-oci11', '--new-bundle-format', + ...this.trustedRootArgs(), '--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com', '--certificate-identity-regexp', opts.certificateIdentityRegexp ]; @@ -353,6 +360,7 @@ export class Sigstore { const cosignArgs = [ 'verify-blob-attestation', '--new-bundle-format', + ...this.trustedRootArgs(), '--certificate-oidc-issuer', 'https://token.actions.githubusercontent.com', '--certificate-identity-regexp', opts.certificateIdentityRegexp, '--type', opts.predicateType ?? COSIGN_PREDICATE_SLSA_PROVENANCE_V1 @@ -432,6 +440,13 @@ export class Sigstore { }; } + private trustedRootArgs(): Array { + if (!fs.existsSync(this.trustedRootPath)) { + throw new Error(`Sigstore trusted root not found at ${this.trustedRootPath}`); + } + return [`--trusted-root=${this.trustedRootPath}`]; + } + private static noTransparencyLog(noTransparencyLog?: boolean): boolean { return noTransparencyLog ?? GitHub.context.payload.repository?.private; } diff --git a/src/sigstore/trusted_root.json b/src/sigstore/trusted_root.json new file mode 100644 index 00000000..effb0a19 --- /dev/null +++ b/src/sigstore/trusted_root.json @@ -0,0 +1,126 @@ +{ + "mediaType": "application/vnd.dev.sigstore.trustedroot+json;version=0.1", + "tlogs": [ + { + "baseUrl": "https://rekor.sigstore.dev", + "hashAlgorithm": "SHA2_256", + "publicKey": { + "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==", + "keyDetails": "PKIX_ECDSA_P256_SHA_256", + "validFor": { + "start": "2021-01-12T11:53:27Z" + } + }, + "logId": { + "keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0=" + } + }, + { + "baseUrl": "https://log2025-1.rekor.sigstore.dev", + "hashAlgorithm": "SHA2_256", + "publicKey": { + "rawBytes": "MCowBQYDK2VwAyEAt8rlp1knGwjfbcXAYPYAkn0XiLz1x8O4t0YkEhie244=", + "keyDetails": "PKIX_ED25519", + "validFor": { + "start": "2025-09-23T00:00:00Z" + } + }, + "logId": { + "keyId": "zxGZFVvd0FEmjR8WrFwMdcAJ9vtaY/QXf44Y1wUeP6A=" + } + } + ], + "certificateAuthorities": [ + { + "subject": { + "organization": "sigstore.dev", + "commonName": "sigstore" + }, + "uri": "https://fulcio.sigstore.dev", + "certChain": { + "certificates": [ + { + "rawBytes": "MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ==" + } + ] + }, + "validFor": { + "start": "2021-03-07T03:20:29Z", + "end": "2022-12-31T23:59:59.999Z" + } + }, + { + "subject": { + "organization": "sigstore.dev", + "commonName": "sigstore" + }, + "uri": "https://fulcio.sigstore.dev", + "certChain": { + "certificates": [ + { + "rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow=" + }, + { + "rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ" + } + ] + }, + "validFor": { + "start": "2022-04-13T20:06:15Z" + } + } + ], + "ctlogs": [ + { + "baseUrl": "https://ctfe.sigstore.dev/test", + "hashAlgorithm": "SHA2_256", + "publicKey": { + "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbfwR+RJudXscgRBRpKX1XFDy3PyudDxz/SfnRi1fT8ekpfBd2O1uoz7jr3Z8nKzxA69EUQ+eFCFI3zeubPWU7w==", + "keyDetails": "PKIX_ECDSA_P256_SHA_256", + "validFor": { + "start": "2021-03-14T00:00:00Z", + "end": "2022-10-31T23:59:59.999Z" + } + }, + "logId": { + "keyId": "CGCS8ChS/2hF0dFrJ4ScRWcYrBY9wzjSbea8IgY2b3I=" + } + }, + { + "baseUrl": "https://ctfe.sigstore.dev/2022", + "hashAlgorithm": "SHA2_256", + "publicKey": { + "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPSlFi0CmFTfEjCUqF9HuCEcYXNKAaYalIJmBZ8yyezPjTqhxrKBpMnaocVtLJBI1eM3uXnQzQGAJdJ4gs9Fyw==", + "keyDetails": "PKIX_ECDSA_P256_SHA_256", + "validFor": { + "start": "2022-10-20T00:00:00Z" + } + }, + "logId": { + "keyId": "3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4=" + } + } + ], + "timestampAuthorities": [ + { + "subject": { + "organization": "sigstore.dev", + "commonName": "sigstore-tsa-selfsigned" + }, + "uri": "https://timestamp.sigstore.dev/api/v1/timestamp", + "certChain": { + "certificates": [ + { + "rawBytes": "MIICEDCCAZagAwIBAgIUOhNULwyQYe68wUMvy4qOiyojiwwwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ra2Z8hKNig2T9kFjCAToGG30jky+WQv3BzL+mKvh1SKNR/UwuwsfNCg4sryoYAd8E6isovVA3M4aoNdm9QDi50Z8nTEyvqgfDPtTIwXItfiW/AFf1V7uwkbkAoj0xxco2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIn9eUOHz9BlRsMCRscsc1t9tOsDMB8GA1UdIwQYMBaAFJjsAe9/u1H/1JUeb4qImFMHic6/MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2gAMGUCMDtpsV/6KaO0qyF/UMsX2aSUXKQFdoGTptQGc0ftq1csulHPGG6dsmyMNd3JB+G3EQIxAOajvBcjpJmKb4Nv+2Taoj8Uc5+b6ih6FXCCKraSqupe07zqswMcXJTe1cExvHvvlw==" + }, + { + "rawBytes": "MIIB9zCCAXygAwIBAgIUV7f0GLDOoEzIh8LXSW80OJiUp14wCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQUQNtfRT/ou3YATa6wB/kKTe70cfJwyRIBovMnt8RcJph/COE82uyS6FmppLLL1VBPGcPfpQPYJNXzWwi8icwhKQ6W/Qe2h3oebBb2FHpwNJDqo+TMaC/tdfkv/ElJB72jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAKBggqhkjOPQQDAwNpADBmAjEAwGEGrfGZR1cen1R8/DTVMI943LssZmJRtDp/i7SfGHmGRP6gRbuj9vOK3b67Z0QQAjEAuT2H673LQEaHTcyQSZrkp4mX7WwkmF+sVbkYY5mXN+RMH13KUEHHOqASaemYWK/E" + } + ] + }, + "validFor": { + "start": "2025-07-04T00:00:00Z" + } + } + ] +} From f0e17b547f2db9c91ab806a5f54ddcae3755b7be Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 18 May 2026 10:46:00 +0200 Subject: [PATCH 2/3] sigstore: use local trusted root for JS verification Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- package.json | 2 +- src/sigstore/sigstore.ts | 14 ++++++--- yarn.lock | 68 +--------------------------------------- 3 files changed, 12 insertions(+), 72 deletions(-) diff --git a/package.json b/package.json index 8eb549f3..1ce4ca0c 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,8 @@ "@actions/io": "^3.0.2", "@actions/tool-cache": "^4.0.0", "@sigstore/bundle": "^4.0.0", + "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.1", - "@sigstore/tuf": "^4.0.2", "@sigstore/verify": "^3.1.0", "async-retry": "^1.3.3", "csv-parse": "^6.2.1", diff --git a/src/sigstore/sigstore.ts b/src/sigstore/sigstore.ts index 3de0a8db..1fa5bf36 100644 --- a/src/sigstore/sigstore.ts +++ b/src/sigstore/sigstore.ts @@ -21,8 +21,8 @@ import {fileURLToPath} from 'url'; import * as core from '@actions/core'; import {bundleFromJSON, bundleToJSON, SerializedBundle} from '@sigstore/bundle'; +import {TrustedRoot} from '@sigstore/protobuf-specs'; import {Artifact, Bundle, CIContextProvider, DSSEBundleBuilder, FulcioSigner, RekorWitness, TSAWitness, Witness} from '@sigstore/sign'; -import * as tuf from '@sigstore/tuf'; import {toSignedEntity, toTrustMaterial, Verifier} from '@sigstore/verify'; import {Context} from '../context.js'; @@ -390,9 +390,8 @@ export class Sigstore { const parsedBundle = JSON.parse(fs.readFileSync(bundlePath, 'utf-8')) as SerializedBundle; const bundle = bundleFromJSON(parsedBundle); - core.info(`Fetching Sigstore TUF trusted root metadata`); - const trustedRoot = await tuf.getTrustedRoot(); - const trustMaterial = toTrustMaterial(trustedRoot); + core.info(`Loading Sigstore trusted root from ${this.trustedRootPath}`); + const trustMaterial = toTrustMaterial(this.trustedRoot()); try { core.info(`Verifying artifact signature`); @@ -447,6 +446,13 @@ export class Sigstore { return [`--trusted-root=${this.trustedRootPath}`]; } + private trustedRoot(): TrustedRoot { + if (!fs.existsSync(this.trustedRootPath)) { + throw new Error(`Sigstore trusted root not found at ${this.trustedRootPath}`); + } + return TrustedRoot.fromJSON(JSON.parse(fs.readFileSync(this.trustedRootPath, {encoding: 'utf-8'}))); + } + private static noTransparencyLog(noTransparencyLog?: boolean): boolean { return noTransparencyLog ?? GitHub.context.payload.repository?.private; } diff --git a/yarn.lock b/yarn.lock index b14b6329..e7c82395 100644 --- a/yarn.lock +++ b/yarn.lock @@ -415,8 +415,8 @@ __metadata: "@actions/tool-cache": "npm:^4.0.0" "@eslint/js": "npm:^9.39.3" "@sigstore/bundle": "npm:^4.0.0" + "@sigstore/protobuf-specs": "npm:^0.5.0" "@sigstore/sign": "npm:^4.1.1" - "@sigstore/tuf": "npm:^4.0.2" "@sigstore/verify": "npm:^3.1.0" "@types/gunzip-maybe": "npm:^1.4.3" "@types/he": "npm:^1.2.3" @@ -1318,16 +1318,6 @@ __metadata: languageName: node linkType: hard -"@sigstore/tuf@npm:^4.0.2": - version: 4.0.2 - resolution: "@sigstore/tuf@npm:4.0.2" - dependencies: - "@sigstore/protobuf-specs": "npm:^0.5.0" - tuf-js: "npm:^4.1.0" - checksum: 10/14882b8e71be4185ec417744b97a47392a50da00aafd4207a46bb74b40aa019ebf22d928052fd2d31a8da0da1efe7ebebac5a70898b31a74239a1ada997be754 - languageName: node - linkType: hard - "@sigstore/verify@npm:^3.1.0": version: 3.1.0 resolution: "@sigstore/verify@npm:3.1.0" @@ -1353,23 +1343,6 @@ __metadata: languageName: node linkType: hard -"@tufjs/canonical-json@npm:2.0.0": - version: 2.0.0 - resolution: "@tufjs/canonical-json@npm:2.0.0" - checksum: 10/cc719a1d0d0ae1aa1ba551a82c87dcbefac088e433c03a3d8a1d547ea721350e47dab4ab5b0fca40d5c7ab1f4882e72edc39c9eae15bf47c45c43bcb6ee39f4f - languageName: node - linkType: hard - -"@tufjs/models@npm:4.1.0": - version: 4.1.0 - resolution: "@tufjs/models@npm:4.1.0" - dependencies: - "@tufjs/canonical-json": "npm:2.0.0" - minimatch: "npm:^10.1.1" - checksum: 10/144d58b634ff96bba8f3cc2577868a0c5dd5bb4515c191edc2a9971245fe3694603b56f0515fd4f7b2f1fb73642d4a36b59b0094ba773fe1c14550915bc9af43 - languageName: node - linkType: hard - "@types/chai@npm:^5.2.2": version: 5.2.3 resolution: "@types/chai@npm:5.2.3" @@ -3610,25 +3583,6 @@ __metadata: languageName: node linkType: hard -"make-fetch-happen@npm:^15.0.1": - version: 15.0.3 - resolution: "make-fetch-happen@npm:15.0.3" - dependencies: - "@npmcli/agent": "npm:^4.0.0" - cacache: "npm:^20.0.1" - http-cache-semantics: "npm:^4.1.1" - minipass: "npm:^7.0.2" - minipass-fetch: "npm:^5.0.0" - minipass-flush: "npm:^1.0.5" - minipass-pipeline: "npm:^1.2.4" - negotiator: "npm:^1.0.0" - proc-log: "npm:^6.0.0" - promise-retry: "npm:^2.0.1" - ssri: "npm:^13.0.0" - checksum: 10/78da4fc1df83cb596e2bae25aa0653b8a9c6cbdd6674a104894e03be3acfcd08c70b78f06ef6407fbd6b173f6a60672480d78641e693d05eb71c09c13ee35278 - languageName: node - linkType: hard - "make-fetch-happen@npm:^15.0.4": version: 15.0.5 resolution: "make-fetch-happen@npm:15.0.5" @@ -3658,15 +3612,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.1.1": - version: 10.1.1 - resolution: "minimatch@npm:10.1.1" - dependencies: - "@isaacs/brace-expansion": "npm:^5.0.0" - checksum: 10/110f38921ea527022e90f7a5f43721838ac740d0a0c26881c03b57c261354fb9a0430e40b2c56dfcea2ef3c773768f27210d1106f1f2be19cde3eea93f26f45e - languageName: node - linkType: hard - "minimatch@npm:^10.2.2": version: 10.2.4 resolution: "minimatch@npm:10.2.4" @@ -4935,17 +4880,6 @@ __metadata: languageName: node linkType: hard -"tuf-js@npm:^4.1.0": - version: 4.1.0 - resolution: "tuf-js@npm:4.1.0" - dependencies: - "@tufjs/models": "npm:4.1.0" - debug: "npm:^4.4.3" - make-fetch-happen: "npm:^15.0.1" - checksum: 10/ae6d3f3e5de940fd6b9faeab3964f9cbddd8885e6dc01d3db7bacdb009abf31a3fab2e10162fc527781a67b04fb957cda2b6aa0017ce49b695fd3c24167aed97 - languageName: node - linkType: hard - "tunnel@npm:^0.0.6": version: 0.0.6 resolution: "tunnel@npm:0.0.6" From fb687aabff32a569481bb76ebb000477614e92ce Mon Sep 17 00:00:00 2001 From: CrazyMax <1951866+crazy-max@users.noreply.github.com> Date: Mon, 18 May 2026 10:38:07 +0200 Subject: [PATCH 3/3] ci: update Sigstore trusted root in dependency workflow Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com> --- .github/workflows/update-deps.yml | 42 +++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/.github/workflows/update-deps.yml b/.github/workflows/update-deps.yml index 22e2e4e5..30d1241f 100644 --- a/.github/workflows/update-deps.yml +++ b/.github/workflows/update-deps.yml @@ -33,6 +33,7 @@ jobs: - compose - cosign - regctl + - trusted-root - undock steps: - @@ -61,6 +62,7 @@ jobs: script: | const fs = require('fs'); const path = require('path'); + const crypto = require('crypto'); const dep = core.getInput('dep'); @@ -83,6 +85,10 @@ jobs: return [...new Set(values)]; } + function sha256(value) { + return crypto.createHash('sha256').update(value).digest('hex'); + } + function stripLeadingV(value) { return value.startsWith('v') ? value.slice(1) : value; } @@ -264,6 +270,33 @@ jobs: ] }; } + }, + 'trusted-root': { + name: 'Sigstore trusted root', + branch: 'deps/sigstore-trusted-root', + sourceUrl: 'https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json', + async resolve({github}) { + const res = await github.rest.repos.getContent({ + owner: 'sigstore', + repo: 'root-signing', + path: 'targets/trusted_root.json', + ref: 'main' + }); + if (Array.isArray(res.data) || res.data.type !== 'file' || !res.data.content) { + throw new Error('Unable to resolve Sigstore trusted_root.json content'); + } + const content = `${Buffer.from(res.data.content, res.data.encoding).toString('utf8').trim()}\n`; + return { + titleValue: res.data.sha.slice(0, 12), + targets: [ + { + path: 'src/sigstore/trusted_root.json', + key: 'trusted_root.json', + content + } + ] + }; + } } }; @@ -280,6 +313,15 @@ jobs: for (const target of resolved.targets) { const absolutePath = path.join(process.env.GITHUB_WORKSPACE, target.path); const content = fs.readFileSync(absolutePath, 'utf8'); + if (target.content !== undefined) { + currentValues.push(sha256(content).slice(0, 12)); + if (content === target.content) { + continue; + } + fs.writeFileSync(absolutePath, target.content, 'utf8'); + changedFiles.push(target.path); + continue; + } const match = content.match(target.pattern); if (!match) { throw new Error(`Missing ${target.key} in ${target.path}`);