@actions/attest
Advanced tools
| import { RequestHeaders } from '@octokit/types'; | ||
| /** | ||
| * Options for creating a storage record for an attested artifact. | ||
| */ | ||
| export type ArtifactOptions = { | ||
| name: string; | ||
| digest: string; | ||
| version?: string; | ||
| status?: string; | ||
| }; | ||
| export type PackageRegistryOptions = { | ||
| registryUrl: string; | ||
| artifactUrl?: string; | ||
| repo?: string; | ||
| path?: string; | ||
| }; | ||
| /** | ||
| * Writes a storage record on behalf of an artifact that has been attested | ||
| * @param artifactOptions - parameters for the storage record API request. | ||
| * @param packageRegistryOptions - parameters for the package registry API request. | ||
| * @param token - GitHub token used to authenticate the request. | ||
| * @param retryAttempts - The number of retries to attempt if the request fails. | ||
| * @param headers - Additional headers to include in the request. | ||
| * | ||
| * @returns The ID of the storage record. | ||
| * @throws Error if the storage record fails to persist. | ||
| */ | ||
| export declare function createStorageRecord(artifactOptions: ArtifactOptions, packageRegistryOptions: PackageRegistryOptions, token: string, retryAttempts?: number, headers?: RequestHeaders): Promise<number[]>; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
| Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
| }) : function(o, v) { | ||
| o["default"] = v; | ||
| }); | ||
| var __importStar = (this && this.__importStar) || (function () { | ||
| var ownKeys = function(o) { | ||
| ownKeys = Object.getOwnPropertyNames || function (o) { | ||
| var ar = []; | ||
| for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; | ||
| return ar; | ||
| }; | ||
| return ownKeys(o); | ||
| }; | ||
| return function (mod) { | ||
| if (mod && mod.__esModule) return mod; | ||
| var result = {}; | ||
| if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); | ||
| __setModuleDefault(result, mod); | ||
| return result; | ||
| }; | ||
| })(); | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __rest = (this && this.__rest) || function (s, e) { | ||
| var t = {}; | ||
| for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
| t[p] = s[p]; | ||
| if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
| for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
| if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
| t[p[i]] = s[p[i]]; | ||
| } | ||
| return t; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createStorageRecord = createStorageRecord; | ||
| const github = __importStar(require("@actions/github")); | ||
| const plugin_retry_1 = require("@octokit/plugin-retry"); | ||
| const CREATE_STORAGE_RECORD_REQUEST = 'POST /orgs/{owner}/artifacts/metadata/storage-record'; | ||
| const DEFAULT_RETRY_COUNT = 5; | ||
| /** | ||
| * Writes a storage record on behalf of an artifact that has been attested | ||
| * @param artifactOptions - parameters for the storage record API request. | ||
| * @param packageRegistryOptions - parameters for the package registry API request. | ||
| * @param token - GitHub token used to authenticate the request. | ||
| * @param retryAttempts - The number of retries to attempt if the request fails. | ||
| * @param headers - Additional headers to include in the request. | ||
| * | ||
| * @returns The ID of the storage record. | ||
| * @throws Error if the storage record fails to persist. | ||
| */ | ||
| function createStorageRecord(artifactOptions, packageRegistryOptions, token, retryAttempts, headers) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const retries = retryAttempts !== null && retryAttempts !== void 0 ? retryAttempts : DEFAULT_RETRY_COUNT; | ||
| const octokit = github.getOctokit(token, { retry: { retries } }, plugin_retry_1.retry); | ||
| try { | ||
| const response = yield octokit.request(CREATE_STORAGE_RECORD_REQUEST, Object.assign({ owner: github.context.repo.owner, headers }, buildRequestParams(artifactOptions, packageRegistryOptions))); | ||
| const data = typeof response.data == 'string' | ||
| ? JSON.parse(response.data) | ||
| : response.data; | ||
| return data === null || data === void 0 ? void 0 : data.storage_records.map((r) => r.id); | ||
| } | ||
| catch (err) { | ||
| const message = err instanceof Error ? err.message : err; | ||
| throw new Error(`Failed to persist storage record: ${message}`); | ||
| } | ||
| }); | ||
| } | ||
| function buildRequestParams(artifactOptions, packageRegistryOptions) { | ||
| const { registryUrl, artifactUrl } = packageRegistryOptions, rest = __rest(packageRegistryOptions, ["registryUrl", "artifactUrl"]); | ||
| return Object.assign(Object.assign(Object.assign({}, artifactOptions), { registry_url: registryUrl, artifact_url: artifactUrl }), rest); | ||
| } | ||
| //# sourceMappingURL=artifactMetadata.js.map |
| {"version":3,"file":"artifactMetadata.js","sourceRoot":"","sources":["../src/artifactMetadata.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,kDA0BC;AAvED,wDAAyC;AACzC,wDAA2C;AAG3C,MAAM,6BAA6B,GACjC,sDAAsD,CAAA;AACxD,MAAM,mBAAmB,GAAG,CAAC,CAAA;AA4B7B;;;;;;;;;;GAUG;AACH,SAAsB,mBAAmB,CACvC,eAAgC,EAChC,sBAA8C,EAC9C,KAAa,EACb,aAAsB,EACtB,OAAwB;;QAExB,MAAM,OAAO,GAAG,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,mBAAmB,CAAA;QACpD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAC,KAAK,EAAE,EAAC,OAAO,EAAC,EAAC,EAAE,oBAAK,CAAC,CAAA;QACnE,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,6BAA6B,kBAClE,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAChC,OAAO,IACJ,kBAAkB,CAAC,eAAe,EAAE,sBAAsB,CAAC,EAC9D,CAAA;YAEF,MAAM,IAAI,GACR,OAAO,QAAQ,CAAC,IAAI,IAAI,QAAQ;gBAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC3B,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAA;YAEnB,OAAO,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAe,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAA;YACxD,MAAM,IAAI,KAAK,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;CAAA;AAED,SAAS,kBAAkB,CACzB,eAAgC,EAChC,sBAA8C;IAE9C,MAAM,EAAC,WAAW,EAAE,WAAW,KAAa,sBAAsB,EAA9B,IAAI,UAAI,sBAAsB,EAA5D,8BAAmC,CAAyB,CAAA;IAClE,qDACK,eAAe,KAClB,YAAY,EAAE,WAAW,EACzB,YAAY,EAAE,WAAW,KACtB,IAAI,EACR;AACH,CAAC"} |
+1
-0
@@ -0,1 +1,2 @@ | ||
| export { createStorageRecord } from './artifactMetadata'; | ||
| export { AttestOptions, attest } from './attest'; | ||
@@ -2,0 +3,0 @@ export { AttestProvenanceOptions, attestProvenance, buildSLSAProvenancePredicate } from './provenance'; |
+3
-1
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.buildSLSAProvenancePredicate = exports.attestProvenance = exports.attest = void 0; | ||
| exports.buildSLSAProvenancePredicate = exports.attestProvenance = exports.attest = exports.createStorageRecord = void 0; | ||
| var artifactMetadata_1 = require("./artifactMetadata"); | ||
| Object.defineProperty(exports, "createStorageRecord", { enumerable: true, get: function () { return artifactMetadata_1.createStorageRecord; } }); | ||
| var attest_1 = require("./attest"); | ||
@@ -5,0 +7,0 @@ Object.defineProperty(exports, "attest", { enumerable: true, get: function () { return attest_1.attest; } }); |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAA8C;AAAvB,gGAAA,MAAM,OAAA;AAC7B,2CAIqB;AAFnB,8GAAA,gBAAgB,OAAA;AAChB,0HAAA,4BAA4B,OAAA"} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAAsD;AAA9C,uHAAA,mBAAmB,OAAA;AAC3B,mCAA8C;AAAvB,gGAAA,MAAM,OAAA;AAC7B,2CAIqB;AAFnB,8GAAA,gBAAgB,OAAA;AAChB,0HAAA,4BAA4B,OAAA"} |
+2
-2
| { | ||
| "name": "@actions/attest", | ||
| "version": "2.0.0", | ||
| "version": "2.1.0", | ||
| "description": "Actions attestation lib", | ||
@@ -58,2 +58,2 @@ "keywords": [ | ||
| } | ||
| } | ||
| } |
+76
-0
@@ -18,2 +18,10 @@ # `@actions/attest` | ||
| ## Table of Contents | ||
| - [Usage](#usage) | ||
| - [attest](#attest) | ||
| - [attestProvenance](#attestprovenance) | ||
| - [Attestation](#attestation) | ||
| - [Sigstore Instance](#sigstore-instance) | ||
| - [Storage](#storage) | ||
| ## Usage | ||
@@ -169,2 +177,70 @@ | ||
| ### createStorageRecord | ||
| The `createStorageRecord` function creates an | ||
| [artifact metadata storage record](https://docs.github.com/en/rest/orgs/artifact-metadata?apiVersion=2022-11-28#create-artifact-metadata-storage-record) | ||
| on behalf of an attested artifact. It accepts parameters defining artifact | ||
| and package registry details. The storage record contains metadata about where the artifact is stored on a given package registry. | ||
| ```js | ||
| const { createStorageRecord } = require('@actions/attest'); | ||
| const core = require('@actions/core'); | ||
| async function run() { | ||
| // In order to persist attestations to the repo, this should be a token with | ||
| // repository write permissions. | ||
| const ghToken = core.getInput('gh-token'); | ||
| const record = await createStorageRecord( | ||
| artifactOptions: { | ||
| name: 'my-artifact-name', | ||
| digest: { 'sha256': '36ab4667...'}, | ||
| version: "v1.0.0" | ||
| }, | ||
| packageRegistryOptions: { | ||
| registryUrl: "https://my-fave-pkg-registry.com" | ||
| }, | ||
| token: ghToken | ||
| ); | ||
| console.log(record); | ||
| } | ||
| run(); | ||
| ``` | ||
| The `createStorageRecord` function supports the following options: | ||
| ```typescript | ||
| // Artifact details to associate the record with | ||
| export type ArtifactOptions = { | ||
| // The name of the artifact | ||
| name: string | ||
| // The digest of the artifact | ||
| digest: string | ||
| // The version of the artifact | ||
| version?: string | ||
| // The status of the artifact | ||
| status?: string | ||
| } | ||
| // Includes details about the package registry the artifact was published to | ||
| export type PackageRegistryOptions = { | ||
| // The URL of the package registry | ||
| registryUrl: string | ||
| // The URL of the artifact in the package registry | ||
| artifactUrl?: string | ||
| // The package registry repository the artifact was published to. | ||
| repo?: string | ||
| // The path of the artifact in the package registry repository. | ||
| path?: string | ||
| } | ||
| // GitHub token for writing attestations. | ||
| token: string | ||
| // Optional parameters for the write operation. | ||
| // The number of times to retry the request. | ||
| retryAttempts?: number | ||
| // HTTP headers to include in request to Artifact Metadata API. | ||
| headers?: RequestHeaders | ||
| ``` | ||
| ## Sigstore Instance | ||
@@ -171,0 +247,0 @@ |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
59451
20.47%33
10%841
17.13%268
39.58%