diff --git a/packages/attest/__tests__/intoto.test.ts b/packages/attest/__tests__/intoto.test.ts index dd6a1a95..c69f7d84 100644 --- a/packages/attest/__tests__/intoto.test.ts +++ b/packages/attest/__tests__/intoto.test.ts @@ -17,7 +17,7 @@ describe('buildIntotoStatement', () => { } it('returns an intoto statement', () => { - const statement = buildIntotoStatement(subject, predicate) + const statement = buildIntotoStatement([subject], predicate) expect(statement).toMatchSnapshot() }) }) diff --git a/packages/attest/__tests__/provenance.test.ts b/packages/attest/__tests__/provenance.test.ts index f4ac707e..3ea208c6 100644 --- a/packages/attest/__tests__/provenance.test.ts +++ b/packages/attest/__tests__/provenance.test.ts @@ -5,6 +5,7 @@ import nock from 'nock' import {MockAgent, setGlobalDispatcher} from 'undici' import {SIGSTORE_PUBLIC_GOOD, signingEndpoints} from '../src/endpoints' import {attestProvenance, buildSLSAProvenancePredicate} from '../src/provenance' +import type {Subject} from '../src/shared.types' describe('provenance functions', () => { const originalEnv = process.env @@ -79,6 +80,22 @@ describe('provenance functions', () => { sha256: '7d070f6b64d9bcc530fe99cc21eaaa4b3c364e0b2d367d7735671fa202a03b32' } + const subjects: Subject[] = [ + { + name: 'subjective', + digest: { + sha256: + '7d070f6b64d9bcc530fe99cc21eaaa4b3c364e0b2d367d7735671fa202a03b32' + } + }, + { + name: 'subject_two', + digest: { + gitcommit: 'c6b487124a61d7dc6c7bd6ea0208368af3513a6e' + } + } + ] + // Fake an OIDC token const oidcPayload = {sub: 'foo@bar.com', iss: ''} const oidcToken = `.${Buffer.from(JSON.stringify(oidcPayload)).toString( @@ -114,8 +131,7 @@ describe('provenance functions', () => { describe('when the sigstore instance is explicitly set', () => { it('attests provenance', async () => { const attestation = await attestProvenance({ - subjectName, - subjectDigest, + subjects, token: 'token', sigstore: 'github', issuer diff --git a/packages/attest/src/attest.ts b/packages/attest/src/attest.ts index 430f2413..67dd68bf 100644 --- a/packages/attest/src/attest.ts +++ b/packages/attest/src/attest.ts @@ -15,10 +15,16 @@ const INTOTO_PAYLOAD_TYPE = 'application/vnd.in-toto+json' */ export type AttestOptions = { // The name of the subject to be attested. - subjectName: string + // @deprecated see 'subjects' + subjectName?: string // The digest of the subject to be attested. Should be a map of digest // algorithms to their hex-encoded values. - subjectDigest: Record + // @deprecated see 'subjects' + subjectDigest?: Record + // The subjects to be attested + // Includes the digest(s) of the subject to be attested. Should be a map of digest + // algorithms to their hex-encoded values. + subjects?: Subject[] // Content type of the predicate being attested. predicateType: string // Predicate to be attested. @@ -40,10 +46,18 @@ export type AttestOptions = { * @returns A promise that resolves to the attestation. */ export async function attest(options: AttestOptions): Promise { - const subject: Subject = { - name: options.subjectName, - digest: options.subjectDigest + let subject = [] as Subject[] + if (options.subjects && options.subjects.length > 0) { + subject = options.subjects + } else if (options.subjectName && options.subjectDigest) { + subject = [ + { + name: options.subjectName, + digest: options.subjectDigest + } + ] } + const predicate: Predicate = { type: options.predicateType, params: options.predicate diff --git a/packages/attest/src/intoto.ts b/packages/attest/src/intoto.ts index 9d6a2d0e..616c0b6d 100644 --- a/packages/attest/src/intoto.ts +++ b/packages/attest/src/intoto.ts @@ -20,12 +20,12 @@ export type InTotoStatement = { * @returns The constructed in-toto statement. */ export const buildIntotoStatement = ( - subject: Subject, + subject: Subject[], predicate: Predicate ): InTotoStatement => { return { _type: INTOTO_STATEMENT_V1_TYPE, - subject: [subject], + subject, predicateType: predicate.type, predicate: predicate.params }