Compare commits
6 Commits
predicate@
...
predicate@
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d58ddf9f24 | ||
|
|
f9d4126c51 | ||
|
|
588eda318e | ||
|
|
48f71d5e11 | ||
|
|
210c191353 | ||
|
|
1cb5f7640f |
1
.github/workflows/linter.yml
vendored
1
.github/workflows/linter.yml
vendored
@@ -46,4 +46,5 @@ jobs:
|
|||||||
TYPESCRIPT_DEFAULT_STYLE: prettier
|
TYPESCRIPT_DEFAULT_STYLE: prettier
|
||||||
VALIDATE_ALL_CODEBASE: true
|
VALIDATE_ALL_CODEBASE: true
|
||||||
VALIDATE_JAVASCRIPT_STANDARD: false
|
VALIDATE_JAVASCRIPT_STANDARD: false
|
||||||
|
VALIDATE_TYPESCRIPT_STANDARD: false
|
||||||
VALIDATE_JSCPD: false
|
VALIDATE_JSCPD: false
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ See [action.yml](action.yml)
|
|||||||
# the "subject-digest" parameter be specified. Defaults to false.
|
# the "subject-digest" parameter be specified. Defaults to false.
|
||||||
push-to-registry:
|
push-to-registry:
|
||||||
|
|
||||||
|
# Whether to attach a list of generated attestations to the workflow run
|
||||||
|
# summary page. Defaults to true.
|
||||||
|
show-summary:
|
||||||
|
|
||||||
# The GitHub token used to make authenticated API requests. Default is
|
# The GitHub token used to make authenticated API requests. Default is
|
||||||
# ${{ github.token }}
|
# ${{ github.token }}
|
||||||
github-token:
|
github-token:
|
||||||
|
|||||||
@@ -1,6 +1,45 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`main successfully run main 1`] = `
|
exports[`main when a non-default OIDC issuer is used successfully run main 1`] = `
|
||||||
|
{
|
||||||
|
"buildDefinition": {
|
||||||
|
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
|
||||||
|
"externalParameters": {
|
||||||
|
"workflow": {
|
||||||
|
"path": ".github/workflows/main.yml",
|
||||||
|
"ref": "main",
|
||||||
|
"repository": "https://example-01.ghe.com/owner/repo",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"internalParameters": {
|
||||||
|
"github": {
|
||||||
|
"event_name": "push",
|
||||||
|
"repository_id": "repo-id",
|
||||||
|
"repository_owner_id": "owner-id",
|
||||||
|
"runner_environment": "github-hosted",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"resolvedDependencies": [
|
||||||
|
{
|
||||||
|
"digest": {
|
||||||
|
"gitCommit": "babca52ab0c93ae16539e5923cb0d7403b9a093b",
|
||||||
|
},
|
||||||
|
"uri": "git+https://example-01.ghe.com/owner/repo@refs/heads/main",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"runDetails": {
|
||||||
|
"builder": {
|
||||||
|
"id": "https://example-01.ghe.com/owner/shared/.github/workflows/build.yml@main",
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"invocationId": "https://example-01.ghe.com/owner/repo/actions/runs/run-id/attempts/run-attempt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`main when the default OIDC issuer is used successfully run main 1`] = `
|
||||||
{
|
{
|
||||||
"buildDefinition": {
|
"buildDefinition": {
|
||||||
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
|
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
|
||||||
|
|||||||
@@ -13,61 +13,13 @@ setFailedMock.mockImplementation(() => {})
|
|||||||
describe('main', () => {
|
describe('main', () => {
|
||||||
let outputs = {} as Record<string, string>
|
let outputs = {} as Record<string, string>
|
||||||
const originalEnv = process.env
|
const originalEnv = process.env
|
||||||
const issuer = 'https://token.actions.githubusercontent.com'
|
|
||||||
const audience = 'nobody'
|
|
||||||
const jwksPath = '/.well-known/jwks.json'
|
|
||||||
const tokenPath = '/token'
|
|
||||||
|
|
||||||
const claims = {
|
beforeEach(() => {
|
||||||
iss: issuer,
|
|
||||||
aud: 'nobody',
|
|
||||||
repository: 'owner/repo',
|
|
||||||
ref: 'refs/heads/main',
|
|
||||||
sha: 'babca52ab0c93ae16539e5923cb0d7403b9a093b',
|
|
||||||
workflow_ref: 'owner/repo/.github/workflows/main.yml@main',
|
|
||||||
job_workflow_ref: 'owner/shared/.github/workflows/build.yml@main',
|
|
||||||
event_name: 'push',
|
|
||||||
repository_id: 'repo-id',
|
|
||||||
repository_owner_id: 'owner-id',
|
|
||||||
run_id: 'run-id',
|
|
||||||
run_attempt: 'run-attempt',
|
|
||||||
runner_environment: 'github-hosted'
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
jest.resetAllMocks()
|
jest.resetAllMocks()
|
||||||
|
|
||||||
setOutputMock.mockImplementation((key, value) => {
|
setOutputMock.mockImplementation((key, value) => {
|
||||||
outputs[key] = value
|
outputs[key] = value
|
||||||
})
|
})
|
||||||
|
|
||||||
process.env = {
|
|
||||||
...originalEnv,
|
|
||||||
ACTIONS_ID_TOKEN_REQUEST_URL: `${issuer}${tokenPath}?`,
|
|
||||||
ACTIONS_ID_TOKEN_REQUEST_TOKEN: 'token',
|
|
||||||
GITHUB_SERVER_URL: 'https://github.com',
|
|
||||||
GITHUB_REPOSITORY: claims.repository
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate JWT signing key
|
|
||||||
const key = await jose.generateKeyPair('PS256')
|
|
||||||
|
|
||||||
// Create JWK, JWKS, and JWT
|
|
||||||
const kid = '12345'
|
|
||||||
const jwk = await jose.exportJWK(key.publicKey)
|
|
||||||
const jwks = { keys: [{ ...jwk, kid }] }
|
|
||||||
const jwt = await new jose.SignJWT(claims)
|
|
||||||
.setProtectedHeader({ alg: 'PS256', kid })
|
|
||||||
.sign(key.privateKey)
|
|
||||||
|
|
||||||
// Mock OpenID configuration and JWKS endpoints
|
|
||||||
nock(issuer)
|
|
||||||
.get('/.well-known/openid-configuration')
|
|
||||||
.reply(200, { jwks_uri: `${issuer}${jwksPath}` })
|
|
||||||
nock(issuer).get(jwksPath).reply(200, jwks)
|
|
||||||
|
|
||||||
// Mock OIDC token endpoint for populating the provenance
|
|
||||||
nock(issuer).get(tokenPath).query({ audience }).reply(200, { value: jwt })
|
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -75,14 +27,131 @@ describe('main', () => {
|
|||||||
process.env = originalEnv
|
process.env = originalEnv
|
||||||
})
|
})
|
||||||
|
|
||||||
it('successfully run main', async () => {
|
describe('when the default OIDC issuer is used', () => {
|
||||||
// Run the main function
|
const issuer = 'https://token.actions.githubusercontent.com'
|
||||||
await main.run()
|
const audience = 'nobody'
|
||||||
|
const jwksPath = '/.well-known/jwks.json'
|
||||||
|
const tokenPath = '/token'
|
||||||
|
|
||||||
// Verify that outputs were set correctly
|
const claims = {
|
||||||
expect(setOutputMock).toHaveBeenCalledTimes(2)
|
iss: issuer,
|
||||||
|
aud: 'nobody',
|
||||||
|
repository: 'owner/repo',
|
||||||
|
ref: 'refs/heads/main',
|
||||||
|
sha: 'babca52ab0c93ae16539e5923cb0d7403b9a093b',
|
||||||
|
workflow_ref: 'owner/repo/.github/workflows/main.yml@main',
|
||||||
|
job_workflow_ref: 'owner/shared/.github/workflows/build.yml@main',
|
||||||
|
event_name: 'push',
|
||||||
|
repository_id: 'repo-id',
|
||||||
|
repository_owner_id: 'owner-id',
|
||||||
|
run_id: 'run-id',
|
||||||
|
run_attempt: 'run-attempt',
|
||||||
|
runner_environment: 'github-hosted'
|
||||||
|
}
|
||||||
|
|
||||||
expect(outputs['predicate']).toMatchSnapshot()
|
beforeEach(async () => {
|
||||||
expect(outputs['predicate-type']).toBe('https://slsa.dev/provenance/v1')
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
ACTIONS_ID_TOKEN_REQUEST_URL: `${issuer}${tokenPath}?`,
|
||||||
|
ACTIONS_ID_TOKEN_REQUEST_TOKEN: 'token',
|
||||||
|
GITHUB_SERVER_URL: 'https://github.com',
|
||||||
|
GITHUB_REPOSITORY: claims.repository
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate JWT signing key
|
||||||
|
const key = await jose.generateKeyPair('PS256')
|
||||||
|
|
||||||
|
// Create JWK, JWKS, and JWT
|
||||||
|
const kid = '12345'
|
||||||
|
const jwk = await jose.exportJWK(key.publicKey)
|
||||||
|
const jwks = { keys: [{ ...jwk, kid }] }
|
||||||
|
const jwt = await new jose.SignJWT(claims)
|
||||||
|
.setProtectedHeader({ alg: 'PS256', kid })
|
||||||
|
.sign(key.privateKey)
|
||||||
|
|
||||||
|
// Mock OpenID configuration and JWKS endpoints
|
||||||
|
nock(issuer)
|
||||||
|
.get('/.well-known/openid-configuration')
|
||||||
|
.reply(200, { jwks_uri: `${issuer}${jwksPath}` })
|
||||||
|
nock(issuer).get(jwksPath).reply(200, jwks)
|
||||||
|
|
||||||
|
// Mock OIDC token endpoint for populating the provenance
|
||||||
|
nock(issuer).get(tokenPath).query({ audience }).reply(200, { value: jwt })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('successfully run main', async () => {
|
||||||
|
// Run the main function
|
||||||
|
await main.run()
|
||||||
|
|
||||||
|
// Verify that outputs were set correctly
|
||||||
|
expect(setOutputMock).toHaveBeenCalledTimes(2)
|
||||||
|
|
||||||
|
expect(outputs['predicate']).toMatchSnapshot()
|
||||||
|
expect(outputs['predicate-type']).toBe('https://slsa.dev/provenance/v1')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('when a non-default OIDC issuer is used', () => {
|
||||||
|
const issuer = 'https://token.actions.example-01.ghe.com'
|
||||||
|
const audience = 'nobody'
|
||||||
|
const jwksPath = '/.well-known/jwks.json'
|
||||||
|
const tokenPath = '/token'
|
||||||
|
|
||||||
|
const claims = {
|
||||||
|
iss: issuer,
|
||||||
|
aud: 'nobody',
|
||||||
|
repository: 'owner/repo',
|
||||||
|
ref: 'refs/heads/main',
|
||||||
|
sha: 'babca52ab0c93ae16539e5923cb0d7403b9a093b',
|
||||||
|
workflow_ref: 'owner/repo/.github/workflows/main.yml@main',
|
||||||
|
job_workflow_ref: 'owner/shared/.github/workflows/build.yml@main',
|
||||||
|
event_name: 'push',
|
||||||
|
repository_id: 'repo-id',
|
||||||
|
repository_owner_id: 'owner-id',
|
||||||
|
run_id: 'run-id',
|
||||||
|
run_attempt: 'run-attempt',
|
||||||
|
runner_environment: 'github-hosted'
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
process.env = {
|
||||||
|
...originalEnv,
|
||||||
|
ACTIONS_ID_TOKEN_REQUEST_URL: `${issuer}${tokenPath}?`,
|
||||||
|
ACTIONS_ID_TOKEN_REQUEST_TOKEN: 'token',
|
||||||
|
GITHUB_SERVER_URL: 'https://example-01.ghe.com',
|
||||||
|
GITHUB_REPOSITORY: claims.repository
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate JWT signing key
|
||||||
|
const key = await jose.generateKeyPair('PS256')
|
||||||
|
|
||||||
|
// Create JWK, JWKS, and JWT
|
||||||
|
const kid = '12345'
|
||||||
|
const jwk = await jose.exportJWK(key.publicKey)
|
||||||
|
const jwks = { keys: [{ ...jwk, kid }] }
|
||||||
|
const jwt = await new jose.SignJWT(claims)
|
||||||
|
.setProtectedHeader({ alg: 'PS256', kid })
|
||||||
|
.sign(key.privateKey)
|
||||||
|
|
||||||
|
// Mock OpenID configuration and JWKS endpoints
|
||||||
|
nock(issuer)
|
||||||
|
.get('/.well-known/openid-configuration')
|
||||||
|
.reply(200, { jwks_uri: `${issuer}${jwksPath}` })
|
||||||
|
nock(issuer).get(jwksPath).reply(200, jwks)
|
||||||
|
|
||||||
|
// Mock OIDC token endpoint for populating the provenance
|
||||||
|
nock(issuer).get(tokenPath).query({ audience }).reply(200, { value: jwt })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('successfully run main', async () => {
|
||||||
|
// Run the main function
|
||||||
|
await main.run()
|
||||||
|
|
||||||
|
// Verify that outputs were set correctly
|
||||||
|
expect(setOutputMock).toHaveBeenCalledTimes(2)
|
||||||
|
|
||||||
|
expect(outputs['predicate']).toMatchSnapshot()
|
||||||
|
expect(outputs['predicate-type']).toBe('https://slsa.dev/provenance/v1')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
11
action.yml
11
action.yml
@@ -30,6 +30,12 @@ inputs:
|
|||||||
and that the "subject-digest" parameter be specified. Defaults to false.
|
and that the "subject-digest" parameter be specified. Defaults to false.
|
||||||
default: false
|
default: false
|
||||||
required: false
|
required: false
|
||||||
|
show-summary:
|
||||||
|
description: >
|
||||||
|
Whether to attach a list of generated attestations to the workflow run
|
||||||
|
summary page. Defaults to true.
|
||||||
|
default: true
|
||||||
|
required: false
|
||||||
github-token:
|
github-token:
|
||||||
description: >
|
description: >
|
||||||
The GitHub token used to make authenticated API requests.
|
The GitHub token used to make authenticated API requests.
|
||||||
@@ -44,9 +50,9 @@ outputs:
|
|||||||
runs:
|
runs:
|
||||||
using: 'composite'
|
using: 'composite'
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/attest-build-provenance/predicate@46e4ff8b824dc6ae13c8f92c8ba69907e2d39b4e # predicate@1.1.0
|
- uses: actions/attest-build-provenance/predicate@9ff3713ef183e028b07415e8a740b634c054a663 # predicate@1.1.1
|
||||||
id: generate-build-provenance-predicate
|
id: generate-build-provenance-predicate
|
||||||
- uses: actions/attest@7305951e905fb742188aa16c1d23409b13565e26 # v1.3.3
|
- uses: actions/attest@2da0b136720d14f01f4dbeeafd1d5a4d76cbe21d # v1.4.0
|
||||||
id: attest
|
id: attest
|
||||||
with:
|
with:
|
||||||
subject-path: ${{ inputs.subject-path }}
|
subject-path: ${{ inputs.subject-path }}
|
||||||
@@ -55,4 +61,5 @@ runs:
|
|||||||
predicate-type: ${{ steps.generate-build-provenance-predicate.outputs.predicate-type }}
|
predicate-type: ${{ steps.generate-build-provenance-predicate.outputs.predicate-type }}
|
||||||
predicate: ${{ steps.generate-build-provenance-predicate.outputs.predicate }}
|
predicate: ${{ steps.generate-build-provenance-predicate.outputs.predicate }}
|
||||||
push-to-registry: ${{ inputs.push-to-registry }}
|
push-to-registry: ${{ inputs.push-to-registry }}
|
||||||
|
show-summary: ${{ inputs.show-summary }}
|
||||||
github-token: ${{ inputs.github-token }}
|
github-token: ${{ inputs.github-token }}
|
||||||
|
|||||||
20
dist/index.js
generated
vendored
20
dist/index.js
generated
vendored
@@ -68862,14 +68862,19 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|||||||
exports.run = run;
|
exports.run = run;
|
||||||
const attest_1 = __nccwpck_require__(74113);
|
const attest_1 = __nccwpck_require__(74113);
|
||||||
const core = __importStar(__nccwpck_require__(42186));
|
const core = __importStar(__nccwpck_require__(42186));
|
||||||
|
const VALID_SERVER_URLS = [
|
||||||
|
'https://github.com',
|
||||||
|
new RegExp('^https://[a-z0-9-]+\\.ghe\\.com$')
|
||||||
|
];
|
||||||
/**
|
/**
|
||||||
* The main function for the action.
|
* The main function for the action.
|
||||||
* @returns {Promise<void>} Resolves when the action is complete.
|
* @returns {Promise<void>} Resolves when the action is complete.
|
||||||
*/
|
*/
|
||||||
async function run() {
|
async function run() {
|
||||||
try {
|
try {
|
||||||
|
const issuer = getIssuer();
|
||||||
// Calculate subject from inputs and generate provenance
|
// Calculate subject from inputs and generate provenance
|
||||||
const predicate = await (0, attest_1.buildSLSAProvenancePredicate)();
|
const predicate = await (0, attest_1.buildSLSAProvenancePredicate)(issuer);
|
||||||
core.setOutput('predicate', predicate.params);
|
core.setOutput('predicate', predicate.params);
|
||||||
core.setOutput('predicate-type', predicate.type);
|
core.setOutput('predicate-type', predicate.type);
|
||||||
}
|
}
|
||||||
@@ -68879,6 +68884,19 @@ async function run() {
|
|||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Derive the current OIDC issuer based on the server URL
|
||||||
|
function getIssuer() {
|
||||||
|
const serverURL = process.env.GITHUB_SERVER_URL || 'https://github.com';
|
||||||
|
// Ensure the server URL is a valid GitHub server URL
|
||||||
|
if (!VALID_SERVER_URLS.some(valid_url => serverURL.match(valid_url))) {
|
||||||
|
throw new Error(`Invalid server URL: ${serverURL}`);
|
||||||
|
}
|
||||||
|
let host = new URL(serverURL).hostname;
|
||||||
|
if (host === 'github.com') {
|
||||||
|
host = 'githubusercontent.com';
|
||||||
|
}
|
||||||
|
return `https://token.actions.${host}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|||||||
155
package-lock.json
generated
155
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "actions/attest-build-provenance",
|
"name": "actions/attest-build-provenance",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "actions/attest-build-provenance",
|
"name": "actions/attest-build-provenance",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/attest": "^1.3.1",
|
"@actions/attest": "^1.3.1",
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
||||||
"@typescript-eslint/parser": "^7.17.0",
|
"@typescript-eslint/parser": "^7.18.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-github": "^5.0.1",
|
"eslint-plugin-github": "^5.0.1",
|
||||||
"eslint-plugin-jest": "^28.6.0",
|
"eslint-plugin-jest": "^28.7.0",
|
||||||
"eslint-plugin-jsonc": "^2.16.0",
|
"eslint-plugin-jsonc": "^2.16.0",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"nock": "^13.5.4",
|
"nock": "^13.5.4",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-eslint": "^16.3.0",
|
"prettier-eslint": "^16.3.0",
|
||||||
"ts-jest": "^29.2.3",
|
"ts-jest": "^29.2.4",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1671,12 +1671,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.0.0",
|
"version": "22.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz",
|
||||||
"integrity": "sha512-VT7KSYudcPOzP5Q0wfbowyNLaVR8QWUdw+088uFWwfvpY6uCWaXpqV6ieLAu9WBcnTa7H4Z5RLK8I5t2FuOcqw==",
|
"integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.11.1"
|
"undici-types": "~6.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/stack-utils": {
|
"node_modules/@types/stack-utils": {
|
||||||
@@ -1731,15 +1731,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "7.17.0",
|
"version": "7.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz",
|
||||||
"integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==",
|
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.17.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/types": "7.17.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
"@typescript-eslint/typescript-estree": "7.17.0",
|
"@typescript-eslint/typescript-estree": "7.18.0",
|
||||||
"@typescript-eslint/visitor-keys": "7.17.0",
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1758,6 +1758,105 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
|
||||||
|
"version": "7.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz",
|
||||||
|
"integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@typescript-eslint/types": "7.18.0",
|
||||||
|
"@typescript-eslint/visitor-keys": "7.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
|
||||||
|
"version": "7.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz",
|
||||||
|
"integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
|
||||||
|
"version": "7.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz",
|
||||||
|
"integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@typescript-eslint/types": "7.18.0",
|
||||||
|
"@typescript-eslint/visitor-keys": "7.18.0",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"globby": "^11.1.0",
|
||||||
|
"is-glob": "^4.0.3",
|
||||||
|
"minimatch": "^9.0.4",
|
||||||
|
"semver": "^7.6.0",
|
||||||
|
"ts-api-utils": "^1.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
|
||||||
|
"version": "7.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz",
|
||||||
|
"integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@typescript-eslint/types": "7.18.0",
|
||||||
|
"eslint-visitor-keys": "^3.4.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^18.18.0 || >=20.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/brace-expansion": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@typescript-eslint/parser/node_modules/minimatch": {
|
||||||
|
"version": "9.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||||
|
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16 || 14 >=14.17"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "7.17.0",
|
"version": "7.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz",
|
||||||
@@ -3392,18 +3491,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jest": {
|
"node_modules/eslint-plugin-jest": {
|
||||||
"version": "28.6.0",
|
"version": "28.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.7.0.tgz",
|
||||||
"integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==",
|
"integrity": "sha512-fzPGN7awL2ftVRQh/bsCi+16ArUZWujZnD1b8EGJqy8nr4//7tZ3BIdc/9edcJBtB3hpci3GtdMNFVDwHU0Eag==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0"
|
"@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^16.10.0 || ^18.12.0 || >=20.0.0"
|
"node": "^16.10.0 || ^18.12.0 || >=20.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0",
|
"@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0",
|
||||||
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0",
|
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0",
|
||||||
"jest": "*"
|
"jest": "*"
|
||||||
},
|
},
|
||||||
@@ -7535,9 +7634,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-jest": {
|
"node_modules/ts-jest": {
|
||||||
"version": "29.2.3",
|
"version": "29.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.4.tgz",
|
||||||
"integrity": "sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==",
|
"integrity": "sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bs-logger": "0.x",
|
"bs-logger": "0.x",
|
||||||
@@ -7776,9 +7875,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.11.1",
|
"version": "6.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz",
|
||||||
"integrity": "sha512-mIDEX2ek50x0OlRgxryxsenE5XaQD4on5U2inY7RApK3SOJpofyw7uW2AyfMKkhAxXIceo2DeWGVGwyvng1GNQ==",
|
"integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/unique-filename": {
|
"node_modules/unique-filename": {
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "actions/attest-build-provenance",
|
"name": "actions/attest-build-provenance",
|
||||||
"description": "Generate signed build provenance attestations",
|
"description": "Generate signed build provenance attestations",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://github.com/actions/attest-build-provenance",
|
"homepage": "https://github.com/actions/attest-build-provenance",
|
||||||
@@ -75,13 +75,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
"@types/node": "^22.0.0",
|
"@types/node": "^22.1.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
"@typescript-eslint/eslint-plugin": "^7.17.0",
|
||||||
"@typescript-eslint/parser": "^7.17.0",
|
"@typescript-eslint/parser": "^7.18.0",
|
||||||
"@vercel/ncc": "^0.38.1",
|
"@vercel/ncc": "^0.38.1",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-github": "^5.0.1",
|
"eslint-plugin-github": "^5.0.1",
|
||||||
"eslint-plugin-jest": "^28.6.0",
|
"eslint-plugin-jest": "^28.7.0",
|
||||||
"eslint-plugin-jsonc": "^2.16.0",
|
"eslint-plugin-jsonc": "^2.16.0",
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"nock": "^13.5.4",
|
"nock": "^13.5.4",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"prettier-eslint": "^16.3.0",
|
"prettier-eslint": "^16.3.0",
|
||||||
"ts-jest": "^29.2.3",
|
"ts-jest": "^29.2.4",
|
||||||
"typescript": "^5.5.4"
|
"typescript": "^5.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/main.ts
27
src/main.ts
@@ -1,14 +1,21 @@
|
|||||||
import { buildSLSAProvenancePredicate } from '@actions/attest'
|
import { buildSLSAProvenancePredicate } from '@actions/attest'
|
||||||
import * as core from '@actions/core'
|
import * as core from '@actions/core'
|
||||||
|
|
||||||
|
const VALID_SERVER_URLS = [
|
||||||
|
'https://github.com',
|
||||||
|
new RegExp('^https://[a-z0-9-]+\\.ghe\\.com$')
|
||||||
|
] as const
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main function for the action.
|
* The main function for the action.
|
||||||
* @returns {Promise<void>} Resolves when the action is complete.
|
* @returns {Promise<void>} Resolves when the action is complete.
|
||||||
*/
|
*/
|
||||||
export async function run(): Promise<void> {
|
export async function run(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
|
const issuer = getIssuer()
|
||||||
|
|
||||||
// Calculate subject from inputs and generate provenance
|
// Calculate subject from inputs and generate provenance
|
||||||
const predicate = await buildSLSAProvenancePredicate()
|
const predicate = await buildSLSAProvenancePredicate(issuer)
|
||||||
|
|
||||||
core.setOutput('predicate', predicate.params)
|
core.setOutput('predicate', predicate.params)
|
||||||
core.setOutput('predicate-type', predicate.type)
|
core.setOutput('predicate-type', predicate.type)
|
||||||
@@ -18,3 +25,21 @@ export async function run(): Promise<void> {
|
|||||||
core.setFailed(error.message)
|
core.setFailed(error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Derive the current OIDC issuer based on the server URL
|
||||||
|
function getIssuer(): string {
|
||||||
|
const serverURL = process.env.GITHUB_SERVER_URL || 'https://github.com'
|
||||||
|
|
||||||
|
// Ensure the server URL is a valid GitHub server URL
|
||||||
|
if (!VALID_SERVER_URLS.some(valid_url => serverURL.match(valid_url))) {
|
||||||
|
throw new Error(`Invalid server URL: ${serverURL}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let host = new URL(serverURL).hostname
|
||||||
|
|
||||||
|
if (host === 'github.com') {
|
||||||
|
host = 'githubusercontent.com'
|
||||||
|
}
|
||||||
|
|
||||||
|
return `https://token.actions.${host}`
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user