@enactprotocol/trust 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/package.json +32 -0
- package/src/hash.ts +120 -0
- package/src/index.ts +28 -0
- package/src/keys.ts +157 -0
- package/src/sigstore/attestation.ts +501 -0
- package/src/sigstore/cosign.ts +564 -0
- package/src/sigstore/index.ts +139 -0
- package/src/sigstore/oauth/client.ts +89 -0
- package/src/sigstore/oauth/index.ts +95 -0
- package/src/sigstore/oauth/server.ts +163 -0
- package/src/sigstore/policy.ts +450 -0
- package/src/sigstore/signing.ts +569 -0
- package/src/sigstore/types.ts +613 -0
- package/src/sigstore/verification.ts +355 -0
- package/src/types.ts +80 -0
- package/tests/hash.test.ts +180 -0
- package/tests/index.test.ts +8 -0
- package/tests/keys.test.ts +147 -0
- package/tests/sigstore/attestation.test.ts +369 -0
- package/tests/sigstore/policy.test.ts +260 -0
- package/tests/sigstore/signing.test.ts +220 -0
- package/tsconfig.json +11 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attestation generation module
|
|
3
|
+
*
|
|
4
|
+
* This module provides functions for creating in-toto attestations and SLSA provenance
|
|
5
|
+
* statements that can be signed using Sigstore.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { hashContent, hashFile } from "../hash";
|
|
9
|
+
import type {
|
|
10
|
+
EnactToolPredicate,
|
|
11
|
+
InTotoStatement,
|
|
12
|
+
InTotoSubject,
|
|
13
|
+
SLSAProvenancePredicate,
|
|
14
|
+
SLSAResourceDescriptor,
|
|
15
|
+
} from "./types";
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Constants
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The primary Enact website/registry URL
|
|
23
|
+
* Used for attestation types, tool URLs, and documentation references
|
|
24
|
+
*/
|
|
25
|
+
export const ENACT_BASE_URL = "https://enact.tools";
|
|
26
|
+
|
|
27
|
+
/** in-toto statement type */
|
|
28
|
+
export const INTOTO_STATEMENT_TYPE = "https://in-toto.io/Statement/v1";
|
|
29
|
+
|
|
30
|
+
/** SLSA Provenance predicate type v1.0 */
|
|
31
|
+
export const SLSA_PROVENANCE_TYPE = "https://slsa.dev/provenance/v1";
|
|
32
|
+
|
|
33
|
+
/** Enact tool attestation predicate type */
|
|
34
|
+
export const ENACT_TOOL_TYPE = `${ENACT_BASE_URL}/attestation/tool/v1`;
|
|
35
|
+
|
|
36
|
+
/** Enact audit attestation predicate type */
|
|
37
|
+
export const ENACT_AUDIT_TYPE = `${ENACT_BASE_URL}/attestation/audit/v1`;
|
|
38
|
+
|
|
39
|
+
/** Enact build type for SLSA provenance */
|
|
40
|
+
export const ENACT_BUILD_TYPE = `${ENACT_BASE_URL}/build/v1`;
|
|
41
|
+
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Subject Creation
|
|
44
|
+
// ============================================================================
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create an in-toto subject from content
|
|
48
|
+
*
|
|
49
|
+
* @param name - The subject name (e.g., file path or artifact identifier)
|
|
50
|
+
* @param content - The content to hash
|
|
51
|
+
* @returns The in-toto subject with sha256 digest
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* const subject = createSubjectFromContent("tool.yaml", yamlContent);
|
|
56
|
+
* // { name: "tool.yaml", digest: { sha256: "abc123..." } }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export function createSubjectFromContent(name: string, content: string | Buffer): InTotoSubject {
|
|
60
|
+
const hash = hashContent(content, "sha256");
|
|
61
|
+
return {
|
|
62
|
+
name,
|
|
63
|
+
digest: {
|
|
64
|
+
sha256: hash.digest,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Create an in-toto subject from a file
|
|
71
|
+
*
|
|
72
|
+
* @param name - The subject name (can differ from file path)
|
|
73
|
+
* @param filePath - Path to the file to hash
|
|
74
|
+
* @returns Promise resolving to the in-toto subject
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const subject = await createSubjectFromFile("my-tool@1.0.0", "/path/to/tool.yaml");
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export async function createSubjectFromFile(
|
|
82
|
+
name: string,
|
|
83
|
+
filePath: string
|
|
84
|
+
): Promise<InTotoSubject> {
|
|
85
|
+
const hash = await hashFile(filePath, { algorithm: "sha256" });
|
|
86
|
+
return {
|
|
87
|
+
name,
|
|
88
|
+
digest: {
|
|
89
|
+
sha256: hash.digest,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Create an in-toto subject with multiple digest algorithms
|
|
96
|
+
*
|
|
97
|
+
* @param name - The subject name
|
|
98
|
+
* @param content - The content to hash
|
|
99
|
+
* @returns Subject with both sha256 and sha512 digests
|
|
100
|
+
*/
|
|
101
|
+
export function createSubjectWithMultipleDigests(
|
|
102
|
+
name: string,
|
|
103
|
+
content: string | Buffer
|
|
104
|
+
): InTotoSubject {
|
|
105
|
+
const sha256 = hashContent(content, "sha256");
|
|
106
|
+
const sha512 = hashContent(content, "sha512");
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
name,
|
|
110
|
+
digest: {
|
|
111
|
+
sha256: sha256.digest,
|
|
112
|
+
sha512: sha512.digest,
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ============================================================================
|
|
118
|
+
// Statement Creation
|
|
119
|
+
// ============================================================================
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Create a generic in-toto statement
|
|
123
|
+
*
|
|
124
|
+
* @param subjects - The subjects (artifacts) covered by this attestation
|
|
125
|
+
* @param predicateType - The predicate type URI
|
|
126
|
+
* @param predicate - The predicate content
|
|
127
|
+
* @returns The in-toto statement
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* const statement = createStatement(
|
|
132
|
+
* [subject],
|
|
133
|
+
* "https://example.com/predicate/v1",
|
|
134
|
+
* { customField: "value" }
|
|
135
|
+
* );
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export function createStatement<T>(
|
|
139
|
+
subjects: InTotoSubject[],
|
|
140
|
+
predicateType: string,
|
|
141
|
+
predicate: T
|
|
142
|
+
): InTotoStatement<T> {
|
|
143
|
+
return {
|
|
144
|
+
_type: INTOTO_STATEMENT_TYPE,
|
|
145
|
+
subject: subjects,
|
|
146
|
+
predicateType,
|
|
147
|
+
predicate,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// SLSA Provenance
|
|
153
|
+
// ============================================================================
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Options for creating SLSA provenance
|
|
157
|
+
*/
|
|
158
|
+
export interface SLSAProvenanceOptions {
|
|
159
|
+
/** Build type URI (e.g., "https://enact.tools/build/v1") */
|
|
160
|
+
buildType: string;
|
|
161
|
+
/** Builder ID (e.g., "https://github.com/enact-dev/enact-cli") */
|
|
162
|
+
builderId: string;
|
|
163
|
+
/** External parameters (inputs to the build) */
|
|
164
|
+
externalParameters?: Record<string, unknown>;
|
|
165
|
+
/** Internal parameters (builder-controlled) */
|
|
166
|
+
internalParameters?: Record<string, unknown>;
|
|
167
|
+
/** Source dependencies */
|
|
168
|
+
resolvedDependencies?: SLSAResourceDescriptor[];
|
|
169
|
+
/** Build invocation ID */
|
|
170
|
+
invocationId?: string;
|
|
171
|
+
/** Build start time */
|
|
172
|
+
startedOn?: Date;
|
|
173
|
+
/** Build finish time */
|
|
174
|
+
finishedOn?: Date;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Create a SLSA provenance predicate
|
|
179
|
+
*
|
|
180
|
+
* @param options - Provenance options
|
|
181
|
+
* @returns The SLSA provenance predicate
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```ts
|
|
185
|
+
* const provenance = createSLSAProvenance({
|
|
186
|
+
* buildType: "https://enact.tools/build/v1",
|
|
187
|
+
* builderId: "https://github.com/enact-dev/enact-cli@v2.0.0",
|
|
188
|
+
* externalParameters: {
|
|
189
|
+
* manifestPath: "tool.yaml"
|
|
190
|
+
* }
|
|
191
|
+
* });
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export function createSLSAProvenance(options: SLSAProvenanceOptions): SLSAProvenancePredicate {
|
|
195
|
+
const provenance: SLSAProvenancePredicate = {
|
|
196
|
+
buildDefinition: {
|
|
197
|
+
buildType: options.buildType,
|
|
198
|
+
externalParameters: options.externalParameters || {},
|
|
199
|
+
},
|
|
200
|
+
runDetails: {
|
|
201
|
+
builder: {
|
|
202
|
+
id: options.builderId,
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// Add optional fields
|
|
208
|
+
if (options.internalParameters) {
|
|
209
|
+
provenance.buildDefinition.internalParameters = options.internalParameters;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (options.resolvedDependencies) {
|
|
213
|
+
provenance.buildDefinition.resolvedDependencies = options.resolvedDependencies;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Add metadata if any timestamps are provided
|
|
217
|
+
if (options.invocationId || options.startedOn || options.finishedOn) {
|
|
218
|
+
provenance.runDetails.metadata = {};
|
|
219
|
+
|
|
220
|
+
if (options.invocationId) {
|
|
221
|
+
provenance.runDetails.metadata.invocationId = options.invocationId;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (options.startedOn) {
|
|
225
|
+
provenance.runDetails.metadata.startedOn = options.startedOn.toISOString();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (options.finishedOn) {
|
|
229
|
+
provenance.runDetails.metadata.finishedOn = options.finishedOn.toISOString();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return provenance;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Create a SLSA provenance statement for an artifact
|
|
238
|
+
*
|
|
239
|
+
* @param subjects - The artifacts to attest
|
|
240
|
+
* @param options - Provenance options
|
|
241
|
+
* @returns The complete in-toto statement with SLSA provenance
|
|
242
|
+
*/
|
|
243
|
+
export function createSLSAProvenanceStatement(
|
|
244
|
+
subjects: InTotoSubject[],
|
|
245
|
+
options: SLSAProvenanceOptions
|
|
246
|
+
): InTotoStatement<SLSAProvenancePredicate> {
|
|
247
|
+
const provenance = createSLSAProvenance(options);
|
|
248
|
+
return createStatement(subjects, SLSA_PROVENANCE_TYPE, provenance);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Enact Tool Attestation
|
|
253
|
+
// ============================================================================
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Options for creating an Enact tool attestation
|
|
257
|
+
*/
|
|
258
|
+
export interface EnactToolAttestationOptions {
|
|
259
|
+
/** Tool name */
|
|
260
|
+
name: string;
|
|
261
|
+
/** Tool version */
|
|
262
|
+
version: string;
|
|
263
|
+
/** Tool publisher identity (email or URI) */
|
|
264
|
+
publisher: string;
|
|
265
|
+
/** Tool description */
|
|
266
|
+
description?: string;
|
|
267
|
+
/** Tool repository URL */
|
|
268
|
+
repository?: string;
|
|
269
|
+
/** Build timestamp */
|
|
270
|
+
buildTimestamp?: Date;
|
|
271
|
+
/** Build environment info */
|
|
272
|
+
buildEnvironment?: Record<string, string>;
|
|
273
|
+
/** Source commit SHA */
|
|
274
|
+
sourceCommit?: string;
|
|
275
|
+
/** Bundle hash (for remote signing) */
|
|
276
|
+
bundleHash?: string;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Create an Enact tool attestation predicate
|
|
281
|
+
*
|
|
282
|
+
* @param options - Tool attestation options
|
|
283
|
+
* @returns The Enact tool predicate
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```ts
|
|
287
|
+
* const toolPredicate = createEnactToolPredicate({
|
|
288
|
+
* name: "my-tool",
|
|
289
|
+
* version: "1.0.0",
|
|
290
|
+
* publisher: "user@example.com",
|
|
291
|
+
* description: "A useful tool"
|
|
292
|
+
* });
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
export function createEnactToolPredicate(options: EnactToolAttestationOptions): EnactToolPredicate {
|
|
296
|
+
const predicate: EnactToolPredicate = {
|
|
297
|
+
type: ENACT_TOOL_TYPE,
|
|
298
|
+
tool: {
|
|
299
|
+
name: options.name,
|
|
300
|
+
version: options.version,
|
|
301
|
+
publisher: options.publisher,
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// Add optional tool fields
|
|
306
|
+
if (options.description) {
|
|
307
|
+
predicate.tool.description = options.description;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (options.repository) {
|
|
311
|
+
predicate.tool.repository = options.repository;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Add build information if provided
|
|
315
|
+
if (options.buildTimestamp || options.buildEnvironment || options.sourceCommit) {
|
|
316
|
+
predicate.build = {
|
|
317
|
+
timestamp: (options.buildTimestamp || new Date()).toISOString(),
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
if (options.buildEnvironment) {
|
|
321
|
+
predicate.build.environment = options.buildEnvironment;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (options.sourceCommit) {
|
|
325
|
+
predicate.build.sourceCommit = options.sourceCommit;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return predicate;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Create an Enact tool attestation statement
|
|
334
|
+
*
|
|
335
|
+
* @param manifestContent - The tool manifest content
|
|
336
|
+
* @param options - Tool attestation options
|
|
337
|
+
* @returns The complete in-toto statement for the tool
|
|
338
|
+
*/
|
|
339
|
+
export function createEnactToolStatement(
|
|
340
|
+
manifestContent: string | Buffer,
|
|
341
|
+
options: EnactToolAttestationOptions
|
|
342
|
+
): InTotoStatement<EnactToolPredicate> {
|
|
343
|
+
const subject = createSubjectFromContent(`${options.name}@${options.version}`, manifestContent);
|
|
344
|
+
const predicate = createEnactToolPredicate(options);
|
|
345
|
+
return createStatement([subject], ENACT_TOOL_TYPE, predicate);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// ============================================================================
|
|
349
|
+
// Enact Audit Attestation
|
|
350
|
+
// ============================================================================
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Options for creating an Enact audit attestation
|
|
354
|
+
*/
|
|
355
|
+
export interface EnactAuditAttestationOptions {
|
|
356
|
+
/** Tool name being audited */
|
|
357
|
+
toolName: string;
|
|
358
|
+
/** Tool version being audited */
|
|
359
|
+
toolVersion: string;
|
|
360
|
+
/** Auditor identity (email or URI) */
|
|
361
|
+
auditor: string;
|
|
362
|
+
/** Audit result */
|
|
363
|
+
result: "passed" | "passed-with-warnings" | "failed";
|
|
364
|
+
/** Audit timestamp */
|
|
365
|
+
timestamp?: Date;
|
|
366
|
+
/** Audit notes */
|
|
367
|
+
notes?: string;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Audit predicate structure
|
|
372
|
+
*/
|
|
373
|
+
export interface EnactAuditPredicate {
|
|
374
|
+
type: typeof ENACT_AUDIT_TYPE;
|
|
375
|
+
tool: {
|
|
376
|
+
name: string;
|
|
377
|
+
version: string;
|
|
378
|
+
};
|
|
379
|
+
audit: {
|
|
380
|
+
auditor: string;
|
|
381
|
+
timestamp: string;
|
|
382
|
+
result: "passed" | "passed-with-warnings" | "failed";
|
|
383
|
+
notes?: string;
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Create an Enact audit attestation predicate
|
|
389
|
+
*
|
|
390
|
+
* @param options - Audit attestation options
|
|
391
|
+
* @returns The Enact audit predicate
|
|
392
|
+
*/
|
|
393
|
+
export function createEnactAuditPredicate(
|
|
394
|
+
options: EnactAuditAttestationOptions
|
|
395
|
+
): EnactAuditPredicate {
|
|
396
|
+
const predicate: EnactAuditPredicate = {
|
|
397
|
+
type: ENACT_AUDIT_TYPE,
|
|
398
|
+
tool: {
|
|
399
|
+
name: options.toolName,
|
|
400
|
+
version: options.toolVersion,
|
|
401
|
+
},
|
|
402
|
+
audit: {
|
|
403
|
+
auditor: options.auditor,
|
|
404
|
+
timestamp: (options.timestamp || new Date()).toISOString(),
|
|
405
|
+
result: options.result,
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
if (options.notes) {
|
|
410
|
+
predicate.audit.notes = options.notes;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return predicate;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Create an Enact audit attestation statement
|
|
418
|
+
*
|
|
419
|
+
* @param manifestContent - The tool manifest content being audited
|
|
420
|
+
* @param options - Audit attestation options
|
|
421
|
+
* @returns The complete in-toto statement for the audit
|
|
422
|
+
*/
|
|
423
|
+
export function createEnactAuditStatement(
|
|
424
|
+
manifestContent: string | Buffer,
|
|
425
|
+
options: EnactAuditAttestationOptions
|
|
426
|
+
): InTotoStatement<EnactAuditPredicate> {
|
|
427
|
+
const subject = createSubjectFromContent(
|
|
428
|
+
`${options.toolName}@${options.toolVersion}`,
|
|
429
|
+
manifestContent
|
|
430
|
+
);
|
|
431
|
+
const predicate = createEnactAuditPredicate(options);
|
|
432
|
+
return createStatement([subject], ENACT_AUDIT_TYPE, predicate);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// ============================================================================
|
|
436
|
+
// Resource Descriptors
|
|
437
|
+
// ============================================================================
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Create a SLSA resource descriptor for a file
|
|
441
|
+
*
|
|
442
|
+
* @param filePath - Path to the file
|
|
443
|
+
* @param options - Additional descriptor options
|
|
444
|
+
* @returns Promise resolving to the resource descriptor
|
|
445
|
+
*/
|
|
446
|
+
export async function createResourceDescriptorFromFile(
|
|
447
|
+
filePath: string,
|
|
448
|
+
options: {
|
|
449
|
+
uri?: string;
|
|
450
|
+
name?: string;
|
|
451
|
+
downloadLocation?: string;
|
|
452
|
+
mediaType?: string;
|
|
453
|
+
} = {}
|
|
454
|
+
): Promise<SLSAResourceDescriptor> {
|
|
455
|
+
const hash = await hashFile(filePath, { algorithm: "sha256" });
|
|
456
|
+
|
|
457
|
+
const descriptor: SLSAResourceDescriptor = {
|
|
458
|
+
name: options.name || filePath,
|
|
459
|
+
digest: {
|
|
460
|
+
sha256: hash.digest,
|
|
461
|
+
},
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
if (options.uri) descriptor.uri = options.uri;
|
|
465
|
+
if (options.downloadLocation) descriptor.downloadLocation = options.downloadLocation;
|
|
466
|
+
if (options.mediaType) descriptor.mediaType = options.mediaType;
|
|
467
|
+
|
|
468
|
+
return descriptor;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Create a SLSA resource descriptor from content
|
|
473
|
+
*
|
|
474
|
+
* @param content - The content
|
|
475
|
+
* @param options - Descriptor options
|
|
476
|
+
* @returns The resource descriptor
|
|
477
|
+
*/
|
|
478
|
+
export function createResourceDescriptorFromContent(
|
|
479
|
+
content: string | Buffer,
|
|
480
|
+
options: {
|
|
481
|
+
uri?: string;
|
|
482
|
+
name?: string;
|
|
483
|
+
downloadLocation?: string;
|
|
484
|
+
mediaType?: string;
|
|
485
|
+
} = {}
|
|
486
|
+
): SLSAResourceDescriptor {
|
|
487
|
+
const hash = hashContent(content, "sha256");
|
|
488
|
+
|
|
489
|
+
const descriptor: SLSAResourceDescriptor = {
|
|
490
|
+
digest: {
|
|
491
|
+
sha256: hash.digest,
|
|
492
|
+
},
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
if (options.uri) descriptor.uri = options.uri;
|
|
496
|
+
if (options.name) descriptor.name = options.name;
|
|
497
|
+
if (options.downloadLocation) descriptor.downloadLocation = options.downloadLocation;
|
|
498
|
+
if (options.mediaType) descriptor.mediaType = options.mediaType;
|
|
499
|
+
|
|
500
|
+
return descriptor;
|
|
501
|
+
}
|