choose proper sigstore instance when attesting (#11)

Signed-off-by: Brian DeHamer <bdehamer@github.com>
This commit is contained in:
Brian DeHamer
2024-02-27 16:47:20 -08:00
committed by GitHub
parent 6e9708eee5
commit 525454b125
7 changed files with 978 additions and 54 deletions

17
__tests__/index.test.ts Normal file
View File

@@ -0,0 +1,17 @@
/**
* Unit tests for the action's entrypoint, src/index.ts
*/
import * as main from '../src/main'
// Mock the action's entrypoint
const runMock = jest.spyOn(main, 'run').mockImplementation()
describe('index', () => {
it('calls run when imported', async () => {
// eslint-disable-next-line @typescript-eslint/no-require-imports
require('../src/index')
expect(runMock).toHaveBeenCalled()
})
})

273
__tests__/main.test.ts Normal file
View File

@@ -0,0 +1,273 @@
/**
* Unit tests for the action's main functionality, src/main.ts
*
* These should be run as if the action was called from a workflow.
* Specifically, the inputs listed in `action.yml` should be set as environment
* variables following the pattern `INPUT_<INPUT_NAME>`.
*/
import * as core from '@actions/core'
import * as github from '@actions/github'
import { mockFulcio, mockRekor, mockTSA } from '@sigstore/mock'
import nock from 'nock'
import { SEARCH_PUBLIC_GOOD_URL } from '../src/endpoints'
import * as main from '../src/main'
// Mock the GitHub Actions core library
const infoMock = jest.spyOn(core, 'info')
const startGroupMock = jest.spyOn(core, 'startGroup')
const getInputMock = jest.spyOn(core, 'getInput')
const getBooleanInputMock = jest.spyOn(core, 'getBooleanInput')
const setOutputMock = jest.spyOn(core, 'setOutput')
const setFailedMock = jest.spyOn(core, 'setFailed')
const summaryWriteMock = jest.spyOn(core.summary, 'write')
summaryWriteMock.mockImplementation(async () => Promise.resolve(core.summary))
// Mock the action's main function
const runMock = jest.spyOn(main, 'run')
describe('action', () => {
// Capture original environment variables and GitHub context so we can restore
// them after each test
const originalEnv = process.env
const originalContext = { ...github.context }
// Fake an OIDC token
const oidcSubject = 'foo@bar.com'
const oidcPayload = { sub: oidcSubject, iss: '' }
const oidcToken = `.${Buffer.from(JSON.stringify(oidcPayload)).toString(
'base64'
)}.}`
const subjectName = 'subject'
const subjectDigest =
'sha256:7d070f6b64d9bcc530fe99cc21eaaa4b3c364e0b2d367d7735671fa202a03b32'
const predicate = '{}'
const predicateType = 'https://in-toto.io/attestation/release/v0.1'
const attestationID = '1234567890'
beforeEach(() => {
jest.clearAllMocks()
// Mock OIDC token endpoint
const tokenURL = 'https://token.url'
nock(tokenURL)
.get('/')
.query({ audience: 'sigstore' })
.reply(200, { value: oidcToken })
nock('https://api.github.com')
.post(/^\/repos\/.*\/.*\/attestations$/)
.reply(201, { id: attestationID })
process.env = {
...originalEnv,
ACTIONS_ID_TOKEN_REQUEST_URL: tokenURL,
ACTIONS_ID_TOKEN_REQUEST_TOKEN: 'token',
RUNNER_TEMP: process.env.RUNNER_TEMP || '/tmp'
}
})
afterEach(() => {
// Restore the original environment
process.env = originalEnv
// Restore the original github.context
setGHContext(originalContext)
})
describe('when ACTIONS_ID_TOKEN_REQUEST_URL is not set', () => {
const inputs = {
'subject-digest': subjectDigest,
'subject-name': subjectName,
'predicate-type': predicateType,
predicate,
'github-token': 'gh-token'
}
beforeEach(() => {
// Nullify the OIDC token URL
process.env.ACTIONS_ID_TOKEN_REQUEST_URL = ''
getInputMock.mockImplementation(mockInput(inputs))
getBooleanInputMock.mockImplementation(() => false)
})
it('sets a failed status', async () => {
await main.run()
expect(runMock).toHaveReturned()
expect(setFailedMock).toHaveBeenCalledWith(
expect.stringMatching(/missing "id-token" permission/)
)
})
})
describe('when no inputs are provided', () => {
beforeEach(() => {
getInputMock.mockImplementation(() => '')
})
it('sets a failed status', async () => {
await main.run()
expect(runMock).toHaveReturned()
expect(setFailedMock).toHaveBeenCalledWith(
expect.stringMatching(
/one of subject-path or subject-digest must be provided/i
)
)
})
})
describe('when the repository is private', () => {
const inputs = {
'subject-digest': subjectDigest,
'subject-name': subjectName,
'predicate-type': predicateType,
predicate,
'github-token': 'gh-token'
}
beforeEach(async () => {
// Set the GH context with private repository visibility and a repo owner.
setGHContext({
payload: { repository: { visibility: 'private' } },
repo: { owner: 'foo', repo: 'bar' }
})
getInputMock.mockImplementation(mockInput(inputs))
getBooleanInputMock.mockImplementation(() => false)
await mockFulcio({
baseURL: 'https://fulcio.githubapp.com',
strict: false
})
await mockTSA({ baseURL: 'https://timestamp.githubapp.com' })
})
it('invokes the action w/o error', async () => {
await main.run()
expect(runMock).toHaveReturned()
expect(setFailedMock).not.toHaveBeenCalledWith()
expect(infoMock).toHaveBeenNthCalledWith(
1,
expect.stringMatching(
`Attestation created for ${subjectName}@${subjectDigest}`
)
)
expect(startGroupMock).toHaveBeenNthCalledWith(
1,
expect.stringMatching('GitHub Sigstore')
)
expect(infoMock).toHaveBeenNthCalledWith(
2,
expect.stringMatching('-----BEGIN CERTIFICATE-----')
)
expect(infoMock).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/attestation uploaded/i)
)
expect(infoMock).toHaveBeenNthCalledWith(
4,
expect.stringMatching(attestationID)
)
expect(setOutputMock).toHaveBeenNthCalledWith(
1,
'bundle-path',
expect.stringMatching('attestation.jsonl')
)
expect(setFailedMock).not.toHaveBeenCalled()
})
})
describe('when the repository is public', () => {
const inputs = {
'subject-digest': subjectDigest,
'subject-name': subjectName,
'predicate-type': predicateType,
predicate,
'github-token': 'gh-token'
}
beforeEach(async () => {
// Set the GH context with public repository visibility and a repo owner.
setGHContext({
payload: { repository: { visibility: 'public' } },
repo: { owner: 'foo', repo: 'bar' }
})
// Mock the action's inputs
getInputMock.mockImplementation(mockInput(inputs))
getBooleanInputMock.mockImplementation(() => false)
await mockFulcio({
baseURL: 'https://fulcio.sigstore.dev',
strict: false
})
await mockRekor({ baseURL: 'https://rekor.sigstore.dev' })
})
it('invokes the action w/o error', async () => {
await main.run()
expect(runMock).toHaveReturned()
expect(setFailedMock).not.toHaveBeenCalled()
expect(infoMock).toHaveBeenNthCalledWith(
1,
expect.stringMatching(
`Attestation created for ${subjectName}@${subjectDigest}`
)
)
expect(startGroupMock).toHaveBeenNthCalledWith(
1,
expect.stringMatching('Public Good Sigstore')
)
expect(infoMock).toHaveBeenNthCalledWith(
2,
expect.stringMatching('-----BEGIN CERTIFICATE-----')
)
expect(infoMock).toHaveBeenNthCalledWith(
3,
expect.stringMatching(/signature uploaded/i)
)
expect(infoMock).toHaveBeenNthCalledWith(
4,
expect.stringMatching(SEARCH_PUBLIC_GOOD_URL)
)
expect(infoMock).toHaveBeenNthCalledWith(
5,
expect.stringMatching(/attestation uploaded/i)
)
expect(infoMock).toHaveBeenNthCalledWith(
6,
expect.stringMatching(attestationID)
)
expect(setOutputMock).toHaveBeenNthCalledWith(
1,
'bundle-path',
expect.stringMatching('attestation.jsonl')
)
expect(setFailedMock).not.toHaveBeenCalled()
})
})
})
function mockInput(inputs: Record<string, string>): typeof core.getInput {
return (name: string): string => {
if (name in inputs) {
return inputs[name]
}
return ''
}
}
// Stubbing the GitHub context is a bit tricky. We need to use
// `Object.defineProperty` because `github.context` is read-only.
function setGHContext(context: object): void {
Object.defineProperty(github, 'context', { value: context })
}

34
dist/index.js generated vendored
View File

@@ -64928,12 +64928,8 @@ function wrappy (fn, cb) {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.TSA_INTERNAL_URL = exports.FULCIO_INTERNAL_URL = exports.SEARCH_PUBLIC_GOOD_URL = exports.REKOR_PUBLIC_GOOD_URL = exports.FULCIO_PUBLIC_GOOD_URL = void 0;
exports.FULCIO_PUBLIC_GOOD_URL = 'https://fulcio.sigstore.dev';
exports.REKOR_PUBLIC_GOOD_URL = 'https://rekor.sigstore.dev';
exports.SEARCH_PUBLIC_GOOD_URL = void 0;
exports.SEARCH_PUBLIC_GOOD_URL = 'https://search.sigstore.dev';
exports.FULCIO_INTERNAL_URL = 'https://fulcio.githubapp.com';
exports.TSA_INTERNAL_URL = 'https://timestamp.githubapp.com';
/***/ }),
@@ -64985,14 +64981,6 @@ const subject_1 = __nccwpck_require__(5206);
const COLOR_CYAN = '\x1B[36m';
const COLOR_DEFAULT = '\x1B[39m';
const ATTESTATION_FILE_NAME = 'attestation.jsonl';
const SIGSTORE_PUBLIC_GOOD_ENDPOINTS = {
fulcioURL: endpoints_1.FULCIO_PUBLIC_GOOD_URL,
rekorURL: endpoints_1.REKOR_PUBLIC_GOOD_URL
};
const SIGSTORE_INTERNAL_ENDPOINTS = {
fulcioURL: endpoints_1.FULCIO_INTERNAL_URL,
tsaServerURL: endpoints_1.TSA_INTERNAL_URL
};
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
@@ -65001,18 +64989,21 @@ async function run() {
// Provenance visibility will be public ONLY if we can confirm that the
// repository is public AND the undocumented "private-signing" arg is NOT set.
// Otherwise, it will be private.
const endpoints = github.context.payload.repository?.visibility === 'public' &&
const sigstoreInstance = github.context.payload.repository?.visibility === 'public' &&
core.getInput('private-signing') !== 'true'
? SIGSTORE_PUBLIC_GOOD_ENDPOINTS
: SIGSTORE_INTERNAL_ENDPOINTS;
? 'public-good'
: 'github';
try {
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
throw new Error('missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.');
}
// Calculate subject from inputs and generate provenance
const subjects = await (0, subject_1.subjectFromInputs)();
const predicate = (0, predicate_1.predicateFromInputs)();
const outputPath = path_1.default.join(tempDir(), ATTESTATION_FILE_NAME);
// Generate attestations for each subject serially
for (const subject of subjects) {
const att = await createAttestation(subject, predicate, endpoints);
const att = await createAttestation(subject, predicate, sigstoreInstance);
// Write attestation bundle to output file
fs_1.default.writeFileSync(outputPath, JSON.stringify(att.bundle) + os_1.default.EOL, {
encoding: 'utf-8',
@@ -65039,17 +65030,19 @@ async function run() {
}
}
exports.run = run;
const createAttestation = async (subject, predicate, endpoints) => {
const createAttestation = async (subject, predicate, sigstoreInstance) => {
// Sign provenance w/ Sigstore
const attestation = await (0, attest_1.attest)({
...endpoints,
subjectName: subject.name,
subjectDigest: subject.digest,
predicateType: predicate.type,
predicate: predicate.params,
sigstore: sigstoreInstance,
token: core.getInput('github-token')
});
core.startGroup(highlight(`Attestation signed using ephemeral certificate from ${endpoints.fulcioURL}`));
core.info(`Attestation created for ${subject.name}@${subjectDigest(subject)}`);
const instanceName = sigstoreInstance === 'public-good' ? 'Public Good' : 'GitHub';
core.startGroup(highlight(`Attestation signed using certificate from ${instanceName} Sigstore instance`));
core.info(attestation.certificate);
core.endGroup();
if (attestation.tlogID) {
@@ -65080,6 +65073,7 @@ const createAttestation = async (subject, predicate, endpoints) => {
const highlight = (str) => `${COLOR_CYAN}${str}${COLOR_DEFAULT}`;
const tempDir = () => {
const basePath = process.env['RUNNER_TEMP'];
/* istanbul ignore if */
if (!basePath) {
throw new Error('Missing RUNNER_TEMP environment variable');
}

652
package-lock.json generated
View File

@@ -15,6 +15,7 @@
"@sigstore/oci": "^0.1.0"
},
"devDependencies": {
"@sigstore/mock": "^0.6.5",
"@types/jest": "^29.5.12",
"@types/make-fetch-happen": "^10.0.4",
"@types/node": "^20.11.21",
@@ -27,6 +28,7 @@
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"js-yaml": "^4.1.0",
"nock": "^13.5.4",
"prettier": "^3.2.5",
"prettier-eslint": "^16.3.0",
"ts-jest": "^29.1.2",
@@ -1464,6 +1466,180 @@
"@octokit/openapi-types": "^19.1.0"
}
},
"node_modules/@peculiar/asn1-cms": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.3.8.tgz",
"integrity": "sha512-Wtk9R7yQxGaIaawHorWKP2OOOm/RZzamOmSWwaqGphIuU6TcKYih0slL6asZlSSZtVoYTrBfrddSOD/jTu9vuQ==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"@peculiar/asn1-x509-attr": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-csr": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.3.8.tgz",
"integrity": "sha512-ZmAaP2hfzgIGdMLcot8gHTykzoI+X/S53x1xoGbTmratETIaAbSWMiPGvZmXRA0SNEIydpMkzYtq4fQBxN1u1w==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-ecc": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.3.8.tgz",
"integrity": "sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-pfx": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.3.8.tgz",
"integrity": "sha512-XhdnCVznMmSmgy68B9pVxiZ1XkKoE1BjO4Hv+eUGiY1pM14msLsFZ3N7K46SoITIVZLq92kKkXpGiTfRjlNLyg==",
"dev": true,
"dependencies": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-pkcs8": "^2.3.8",
"@peculiar/asn1-rsa": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-pkcs8": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.3.8.tgz",
"integrity": "sha512-rL8k2x59v8lZiwLRqdMMmOJ30GHt6yuHISFIuuWivWjAJjnxzZBVzMTQ72sknX5MeTSSvGwPmEFk2/N8+UztFQ==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-pkcs9": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.3.8.tgz",
"integrity": "sha512-+nONq5tcK7vm3qdY7ZKoSQGQjhJYMJbwJGbXLFOhmqsFIxEWyQPHyV99+wshOjpOjg0wUSSkEEzX2hx5P6EKeQ==",
"dev": true,
"dependencies": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-pfx": "^2.3.8",
"@peculiar/asn1-pkcs8": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"@peculiar/asn1-x509-attr": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-rsa": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.3.8.tgz",
"integrity": "sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-schema": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz",
"integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==",
"dev": true,
"dependencies": {
"asn1js": "^3.0.5",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-x509": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.3.8.tgz",
"integrity": "sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"asn1js": "^3.0.5",
"ipaddr.js": "^2.1.0",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/asn1-x509-attr": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.3.8.tgz",
"integrity": "sha512-4Z8mSN95MOuX04Aku9BUyMdsMKtVQUqWnr627IheiWnwFoheUhX3R4Y2zh23M7m80r4/WG8MOAckRKc77IRv6g==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"node_modules/@peculiar/json-schema": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz",
"integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==",
"dev": true,
"dependencies": {
"tslib": "^2.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/@peculiar/webcrypto": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz",
"integrity": "sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/json-schema": "^1.1.12",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2",
"webcrypto-core": "^1.7.8"
},
"engines": {
"node": ">=10.12.0"
}
},
"node_modules/@peculiar/x509": {
"version": "1.9.7",
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.9.7.tgz",
"integrity": "sha512-O+fR1ge6U8upO52q5b3d4tF4SxUdK4IQ0y++Z/Wlqq+ySZUf+deHnbMlDB1YZsIQ/DXU0i5M7Y1DyF5kwpXouQ==",
"dev": true,
"dependencies": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-csr": "^2.3.8",
"@peculiar/asn1-ecc": "^2.3.8",
"@peculiar/asn1-pkcs9": "^2.3.8",
"@peculiar/asn1-rsa": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"pvtsutils": "^1.3.5",
"reflect-metadata": "^0.2.1",
"tslib": "^2.6.2",
"tsyringe": "^4.8.0"
}
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"license": "MIT",
@@ -1500,6 +1676,27 @@
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/@sigstore/mock": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/@sigstore/mock/-/mock-0.6.5.tgz",
"integrity": "sha512-mMWj6SNmM+yGVZ9Qk2sDsVPZuwoPaLGzMFpVGdNeSYNC4HtzdrCihKYxJ+VSo0tdh+X6HwOUKaVtkRsjpY1ZbQ==",
"dev": true,
"dependencies": {
"@peculiar/webcrypto": "^1.4.5",
"@peculiar/x509": "^1.9.7",
"@sigstore/protobuf-specs": "^0.3.0",
"asn1js": "^3.0.5",
"bytestreamjs": "^2.0.1",
"canonicalize": "^2.0.0",
"jose": "^5.2.2",
"nock": "^13.5.1",
"pkijs": "^3.0.15",
"pvutils": "^1.1.3"
},
"engines": {
"node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/@sigstore/oci": {
"version": "0.1.0",
"license": "Apache-2.0",
@@ -2169,6 +2366,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/asn1js": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz",
"integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==",
"dev": true,
"dependencies": {
"pvtsutils": "^1.3.2",
"pvutils": "^1.1.3",
"tslib": "^2.4.0"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/ast-types-flow": {
"version": "0.0.7",
"dev": true,
@@ -2397,6 +2608,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/bytestreamjs": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz",
"integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/cacache": {
"version": "18.0.2",
"license": "ISC",
@@ -2512,6 +2732,12 @@
],
"license": "CC-BY-4.0"
},
"node_modules/canonicalize": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz",
"integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==",
"dev": true
},
"node_modules/chalk": {
"version": "4.1.2",
"dev": true,
@@ -4225,6 +4451,15 @@
"version": "1.1.3",
"license": "BSD-3-Clause"
},
"node_modules/ipaddr.js": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
"integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==",
"dev": true,
"engines": {
"node": ">= 10"
}
},
"node_modules/is-array-buffer": {
"version": "3.0.2",
"dev": true,
@@ -5087,6 +5322,15 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/jose": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz",
"integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"dev": true,
@@ -5138,6 +5382,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"dev": true
},
"node_modules/json5": {
"version": "2.2.3",
"dev": true,
@@ -5642,6 +5892,20 @@
"node": ">= 0.6"
}
},
"node_modules/nock": {
"version": "13.5.4",
"resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz",
"integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==",
"dev": true,
"dependencies": {
"debug": "^4.1.0",
"json-stringify-safe": "^5.0.1",
"propagate": "^2.0.0"
},
"engines": {
"node": ">= 10.13"
}
},
"node_modules/node-int64": {
"version": "0.4.0",
"dev": true,
@@ -6014,6 +6278,22 @@
"node": ">=8"
}
},
"node_modules/pkijs": {
"version": "3.0.15",
"resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.0.15.tgz",
"integrity": "sha512-n7nAl9JpqdeQsjy+rPmswkmZ3oO/Fu5uN9me45PPQVdWjd0X7HKfL8+HYwfxihqoDSSPUIajkOcqFxEUxMqhwQ==",
"dev": true,
"dependencies": {
"asn1js": "^3.0.5",
"bytestreamjs": "^2.0.0",
"pvtsutils": "^1.3.2",
"pvutils": "^1.1.3",
"tslib": "^2.4.0"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"dev": true,
@@ -6128,6 +6408,15 @@
"node": ">= 6"
}
},
"node_modules/propagate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"dev": true,
@@ -6151,6 +6440,24 @@
],
"license": "MIT"
},
"node_modules/pvtsutils": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz",
"integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==",
"dev": true,
"dependencies": {
"tslib": "^2.6.1"
}
},
"node_modules/pvutils": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz",
"integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"dev": true,
@@ -6175,6 +6482,12 @@
"dev": true,
"license": "MIT"
},
"node_modules/reflect-metadata": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz",
"integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==",
"dev": true
},
"node_modules/regenerator-runtime": {
"version": "0.14.0",
"dev": true,
@@ -6881,6 +7194,24 @@
"dev": true,
"license": "0BSD"
},
"node_modules/tsyringe": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.8.0.tgz",
"integrity": "sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==",
"dev": true,
"dependencies": {
"tslib": "^1.9.3"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/tsyringe/node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
"node_modules/tunnel": {
"version": "0.0.6",
"license": "MIT",
@@ -7137,6 +7468,19 @@
"makeerror": "1.0.12"
}
},
"node_modules/webcrypto-core": {
"version": "1.7.8",
"resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.8.tgz",
"integrity": "sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==",
"dev": true,
"dependencies": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/json-schema": "^1.1.12",
"asn1js": "^3.0.1",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"node_modules/which": {
"version": "2.0.2",
"license": "ISC",
@@ -8227,6 +8571,174 @@
"@octokit/openapi-types": "^19.1.0"
}
},
"@peculiar/asn1-cms": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.3.8.tgz",
"integrity": "sha512-Wtk9R7yQxGaIaawHorWKP2OOOm/RZzamOmSWwaqGphIuU6TcKYih0slL6asZlSSZtVoYTrBfrddSOD/jTu9vuQ==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"@peculiar/asn1-x509-attr": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-csr": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.3.8.tgz",
"integrity": "sha512-ZmAaP2hfzgIGdMLcot8gHTykzoI+X/S53x1xoGbTmratETIaAbSWMiPGvZmXRA0SNEIydpMkzYtq4fQBxN1u1w==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-ecc": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.3.8.tgz",
"integrity": "sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-pfx": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.3.8.tgz",
"integrity": "sha512-XhdnCVznMmSmgy68B9pVxiZ1XkKoE1BjO4Hv+eUGiY1pM14msLsFZ3N7K46SoITIVZLq92kKkXpGiTfRjlNLyg==",
"dev": true,
"requires": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-pkcs8": "^2.3.8",
"@peculiar/asn1-rsa": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-pkcs8": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.3.8.tgz",
"integrity": "sha512-rL8k2x59v8lZiwLRqdMMmOJ30GHt6yuHISFIuuWivWjAJjnxzZBVzMTQ72sknX5MeTSSvGwPmEFk2/N8+UztFQ==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-pkcs9": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.3.8.tgz",
"integrity": "sha512-+nONq5tcK7vm3qdY7ZKoSQGQjhJYMJbwJGbXLFOhmqsFIxEWyQPHyV99+wshOjpOjg0wUSSkEEzX2hx5P6EKeQ==",
"dev": true,
"requires": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-pfx": "^2.3.8",
"@peculiar/asn1-pkcs8": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"@peculiar/asn1-x509-attr": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-rsa": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.3.8.tgz",
"integrity": "sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-schema": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz",
"integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==",
"dev": true,
"requires": {
"asn1js": "^3.0.5",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-x509": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.3.8.tgz",
"integrity": "sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"asn1js": "^3.0.5",
"ipaddr.js": "^2.1.0",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"@peculiar/asn1-x509-attr": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.3.8.tgz",
"integrity": "sha512-4Z8mSN95MOuX04Aku9BUyMdsMKtVQUqWnr627IheiWnwFoheUhX3R4Y2zh23M7m80r4/WG8MOAckRKc77IRv6g==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"asn1js": "^3.0.5",
"tslib": "^2.6.2"
}
},
"@peculiar/json-schema": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz",
"integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==",
"dev": true,
"requires": {
"tslib": "^2.0.0"
}
},
"@peculiar/webcrypto": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz",
"integrity": "sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/json-schema": "^1.1.12",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2",
"webcrypto-core": "^1.7.8"
}
},
"@peculiar/x509": {
"version": "1.9.7",
"resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.9.7.tgz",
"integrity": "sha512-O+fR1ge6U8upO52q5b3d4tF4SxUdK4IQ0y++Z/Wlqq+ySZUf+deHnbMlDB1YZsIQ/DXU0i5M7Y1DyF5kwpXouQ==",
"dev": true,
"requires": {
"@peculiar/asn1-cms": "^2.3.8",
"@peculiar/asn1-csr": "^2.3.8",
"@peculiar/asn1-ecc": "^2.3.8",
"@peculiar/asn1-pkcs9": "^2.3.8",
"@peculiar/asn1-rsa": "^2.3.8",
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/asn1-x509": "^2.3.8",
"pvtsutils": "^1.3.5",
"reflect-metadata": "^0.2.1",
"tslib": "^2.6.2",
"tsyringe": "^4.8.0"
}
},
"@pkgjs/parseargs": {
"version": "0.11.0",
"optional": true
@@ -8244,6 +8756,24 @@
"@sigstore/core": {
"version": "1.0.0"
},
"@sigstore/mock": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/@sigstore/mock/-/mock-0.6.5.tgz",
"integrity": "sha512-mMWj6SNmM+yGVZ9Qk2sDsVPZuwoPaLGzMFpVGdNeSYNC4HtzdrCihKYxJ+VSo0tdh+X6HwOUKaVtkRsjpY1ZbQ==",
"dev": true,
"requires": {
"@peculiar/webcrypto": "^1.4.5",
"@peculiar/x509": "^1.9.7",
"@sigstore/protobuf-specs": "^0.3.0",
"asn1js": "^3.0.5",
"bytestreamjs": "^2.0.1",
"canonicalize": "^2.0.0",
"jose": "^5.2.2",
"nock": "^13.5.1",
"pkijs": "^3.0.15",
"pvutils": "^1.1.3"
}
},
"@sigstore/oci": {
"version": "0.1.0",
"requires": {
@@ -8674,6 +9204,17 @@
"is-shared-array-buffer": "^1.0.2"
}
},
"asn1js": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz",
"integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==",
"dev": true,
"requires": {
"pvtsutils": "^1.3.2",
"pvutils": "^1.1.3",
"tslib": "^2.4.0"
}
},
"ast-types-flow": {
"version": "0.0.7",
"dev": true
@@ -8822,6 +9363,12 @@
"version": "1.1.2",
"dev": true
},
"bytestreamjs": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz",
"integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==",
"dev": true
},
"cacache": {
"version": "18.0.2",
"requires": {
@@ -8886,6 +9433,12 @@
"version": "1.0.30001524",
"dev": true
},
"canonicalize": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-2.0.0.tgz",
"integrity": "sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w==",
"dev": true
},
"chalk": {
"version": "4.1.2",
"dev": true,
@@ -9940,6 +10493,12 @@
}
}
},
"ipaddr.js": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
"integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==",
"dev": true
},
"is-array-buffer": {
"version": "3.0.2",
"dev": true,
@@ -10498,6 +11057,12 @@
}
}
},
"jose": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/jose/-/jose-5.2.2.tgz",
"integrity": "sha512-/WByRr4jDcsKlvMd1dRJnPfS1GVO3WuKyaurJ/vvXcOaUQO8rnNObCQMlv/5uCceVQIq5Q4WLF44ohsdiTohdg==",
"dev": true
},
"js-tokens": {
"version": "4.0.0",
"dev": true
@@ -10532,6 +11097,12 @@
"version": "1.0.1",
"dev": true
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"dev": true
},
"json5": {
"version": "2.2.3",
"dev": true
@@ -10859,6 +11430,17 @@
"negotiator": {
"version": "0.6.3"
},
"nock": {
"version": "13.5.4",
"resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz",
"integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==",
"dev": true,
"requires": {
"debug": "^4.1.0",
"json-stringify-safe": "^5.0.1",
"propagate": "^2.0.0"
}
},
"node-int64": {
"version": "0.4.0",
"dev": true
@@ -11080,6 +11662,19 @@
}
}
},
"pkijs": {
"version": "3.0.15",
"resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.0.15.tgz",
"integrity": "sha512-n7nAl9JpqdeQsjy+rPmswkmZ3oO/Fu5uN9me45PPQVdWjd0X7HKfL8+HYwfxihqoDSSPUIajkOcqFxEUxMqhwQ==",
"dev": true,
"requires": {
"asn1js": "^3.0.5",
"bytestreamjs": "^2.0.0",
"pvtsutils": "^1.3.2",
"pvutils": "^1.1.3",
"tslib": "^2.4.0"
}
},
"prelude-ls": {
"version": "1.2.1",
"dev": true
@@ -11143,6 +11738,12 @@
"sisteransi": "^1.0.5"
}
},
"propagate": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
"dev": true
},
"punycode": {
"version": "2.3.1",
"dev": true
@@ -11151,6 +11752,21 @@
"version": "6.0.3",
"dev": true
},
"pvtsutils": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz",
"integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==",
"dev": true,
"requires": {
"tslib": "^2.6.1"
}
},
"pvutils": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz",
"integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==",
"dev": true
},
"queue-microtask": {
"version": "1.2.3",
"dev": true
@@ -11159,6 +11775,12 @@
"version": "18.2.0",
"dev": true
},
"reflect-metadata": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz",
"integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==",
"dev": true
},
"regenerator-runtime": {
"version": "0.14.0",
"dev": true
@@ -11582,6 +12204,23 @@
}
}
},
"tsyringe": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.8.0.tgz",
"integrity": "sha512-YB1FG+axdxADa3ncEtRnQCFq/M0lALGLxSZeVNbTU8NqhOVc51nnv2CISTcvc1kyv6EGPtXVr0v6lWeDxiijOA==",
"dev": true,
"requires": {
"tslib": "^1.9.3"
},
"dependencies": {
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
}
}
},
"tunnel": {
"version": "0.0.6"
},
@@ -11731,6 +12370,19 @@
"makeerror": "1.0.12"
}
},
"webcrypto-core": {
"version": "1.7.8",
"resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.8.tgz",
"integrity": "sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg==",
"dev": true,
"requires": {
"@peculiar/asn1-schema": "^2.3.8",
"@peculiar/json-schema": "^1.1.12",
"asn1js": "^3.0.1",
"pvtsutils": "^1.3.5",
"tslib": "^2.6.2"
}
},
"which": {
"version": "2.0.2",
"requires": {

View File

@@ -71,6 +71,7 @@
"@sigstore/oci": "^0.1.0"
},
"devDependencies": {
"@sigstore/mock": "^0.6.5",
"@types/jest": "^29.5.12",
"@types/make-fetch-happen": "^10.0.4",
"@types/node": "^20.11.21",
@@ -83,6 +84,7 @@
"eslint-plugin-prettier": "^5.1.3",
"jest": "^29.7.0",
"js-yaml": "^4.1.0",
"nock": "^13.5.4",
"prettier": "^3.2.5",
"prettier-eslint": "^16.3.0",
"ts-jest": "^29.1.2",

View File

@@ -1,6 +1 @@
export const FULCIO_PUBLIC_GOOD_URL = 'https://fulcio.sigstore.dev'
export const REKOR_PUBLIC_GOOD_URL = 'https://rekor.sigstore.dev'
export const SEARCH_PUBLIC_GOOD_URL = 'https://search.sigstore.dev'
export const FULCIO_INTERNAL_URL = 'https://fulcio.githubapp.com'
export const TSA_INTERNAL_URL = 'https://timestamp.githubapp.com'

View File

@@ -6,36 +6,16 @@ import { attachArtifactToImage, getRegistryCredentials } from '@sigstore/oci'
import fs from 'fs'
import os from 'os'
import path from 'path'
import {
FULCIO_INTERNAL_URL,
FULCIO_PUBLIC_GOOD_URL,
REKOR_PUBLIC_GOOD_URL,
SEARCH_PUBLIC_GOOD_URL,
TSA_INTERNAL_URL
} from './endpoints'
import { SEARCH_PUBLIC_GOOD_URL } from './endpoints'
import { predicateFromInputs } from './predicate'
import { subjectFromInputs } from './subject'
type Endpoints = {
fulcioURL: string
rekorURL?: string
tsaServerURL?: string
}
type SigstoreInstance = 'public-good' | 'github'
const COLOR_CYAN = '\x1B[36m'
const COLOR_DEFAULT = '\x1B[39m'
const ATTESTATION_FILE_NAME = 'attestation.jsonl'
const SIGSTORE_PUBLIC_GOOD_ENDPOINTS: Endpoints = {
fulcioURL: FULCIO_PUBLIC_GOOD_URL,
rekorURL: REKOR_PUBLIC_GOOD_URL
}
const SIGSTORE_INTERNAL_ENDPOINTS: Endpoints = {
fulcioURL: FULCIO_INTERNAL_URL,
tsaServerURL: TSA_INTERNAL_URL
}
/**
* The main function for the action.
* @returns {Promise<void>} Resolves when the action is complete.
@@ -44,13 +24,19 @@ export async function run(): Promise<void> {
// Provenance visibility will be public ONLY if we can confirm that the
// repository is public AND the undocumented "private-signing" arg is NOT set.
// Otherwise, it will be private.
const endpoints =
const sigstoreInstance: SigstoreInstance =
github.context.payload.repository?.visibility === 'public' &&
core.getInput('private-signing') !== 'true'
? SIGSTORE_PUBLIC_GOOD_ENDPOINTS
: SIGSTORE_INTERNAL_ENDPOINTS
? 'public-good'
: 'github'
try {
if (!process.env.ACTIONS_ID_TOKEN_REQUEST_URL) {
throw new Error(
'missing "id-token" permission. Please add "permissions: id-token: write" to your workflow.'
)
}
// Calculate subject from inputs and generate provenance
const subjects = await subjectFromInputs()
const predicate = predicateFromInputs()
@@ -58,7 +44,7 @@ export async function run(): Promise<void> {
// Generate attestations for each subject serially
for (const subject of subjects) {
const att = await createAttestation(subject, predicate, endpoints)
const att = await createAttestation(subject, predicate, sigstoreInstance)
// Write attestation bundle to output file
fs.writeFileSync(outputPath, JSON.stringify(att.bundle) + os.EOL, {
@@ -97,21 +83,25 @@ export async function run(): Promise<void> {
const createAttestation = async (
subject: Subject,
predicate: Predicate,
endpoints: Endpoints
sigstoreInstance: SigstoreInstance
): Promise<Attestation> => {
// Sign provenance w/ Sigstore
const attestation = await attest({
...endpoints,
subjectName: subject.name,
subjectDigest: subject.digest,
predicateType: predicate.type,
predicate: predicate.params,
sigstore: sigstoreInstance,
token: core.getInput('github-token')
})
core.info(`Attestation created for ${subject.name}@${subjectDigest(subject)}`)
const instanceName =
sigstoreInstance === 'public-good' ? 'Public Good' : 'GitHub'
core.startGroup(
highlight(
`Attestation signed using ephemeral certificate from ${endpoints.fulcioURL}`
`Attestation signed using certificate from ${instanceName} Sigstore instance`
)
)
core.info(attestation.certificate)
@@ -153,6 +143,7 @@ const highlight = (str: string): string => `${COLOR_CYAN}${str}${COLOR_DEFAULT}`
const tempDir = (): string => {
const basePath = process.env['RUNNER_TEMP']
/* istanbul ignore if */
if (!basePath) {
throw new Error('Missing RUNNER_TEMP environment variable')
}