diff --git a/.changeset/tame-clouds-sparkle.md b/.changeset/tame-clouds-sparkle.md new file mode 100644 index 00000000..b59594de --- /dev/null +++ b/.changeset/tame-clouds-sparkle.md @@ -0,0 +1,5 @@ +--- +'@sigstore/sign': major +--- + +Default `RekorWitness` to generating "dsse" entries instead of "intoto" diff --git a/packages/client/src/config.ts b/packages/client/src/config.ts index 4ce71801..160db300 100644 --- a/packages/client/src/config.ts +++ b/packages/client/src/config.ts @@ -167,6 +167,7 @@ function initWitnesses(options: SignOptions): Witness[] { witnesses.push( new RekorWitness({ rekorBaseURL: options.rekorURL, + entryType: 'intoto', fetchOnConflict: false, retry: options.retry ?? DEFAULT_RETRY, timeout: options.timeout ?? DEFAULT_TIMEOUT, diff --git a/packages/sign/src/__tests__/integration.test.ts b/packages/sign/src/__tests__/integration.test.ts index 078c97e5..edbdb159 100644 --- a/packages/sign/src/__tests__/integration.test.ts +++ b/packages/sign/src/__tests__/integration.test.ts @@ -90,7 +90,7 @@ describe('artifact signing', () => { expect(bundle.verificationMaterial.tlogEntries).toHaveLength(1); expect(bundle.verificationMaterial.tlogEntries[0].kindVersion.kind).toBe( - 'intoto' + 'dsse' ); expect( diff --git a/packages/sign/src/__tests__/witness/tlog/entry.test.ts b/packages/sign/src/__tests__/witness/tlog/entry.test.ts index b2f38a84..2da0fe1d 100644 --- a/packages/sign/src/__tests__/witness/tlog/entry.test.ts +++ b/packages/sign/src/__tests__/witness/tlog/entry.test.ts @@ -74,40 +74,16 @@ describe('toProposedEntry', () => { it('return a valid ProposedEntry entry', () => { const entry = toProposedEntry(sigBundle, publicKey); - assert(entry.apiVersion === '0.0.2'); - assert(entry.kind === 'intoto'); + assert(entry.apiVersion === '0.0.1'); + assert(entry.kind === 'dsse'); expect(entry.spec).toBeTruthy(); - expect(entry.spec.content).toBeTruthy(); - expect(entry.spec.content.envelope).toBeTruthy(); - - const e = entry.spec.content.envelope; - expect(e?.payloadType).toEqual(sigBundle.dsseEnvelope.payloadType); - expect(e?.payload).toEqual( - enc.base64Encode(sigBundle.dsseEnvelope.payload.toString('base64')) - ); - expect(e?.signatures).toHaveLength(1); - expect(e?.signatures[0].keyid).toEqual( - sigBundle.dsseEnvelope.signatures[0].keyid - ); - expect(e?.signatures[0].sig).toEqual( - enc.base64Encode( - sigBundle.dsseEnvelope.signatures[0].sig.toString('base64') - ) - ); - expect(e?.signatures[0].publicKey).toEqual(enc.base64Encode(publicKey)); - - expect(entry.spec.content.payloadHash).toBeTruthy(); - expect(entry.spec.content.payloadHash?.algorithm).toBe('sha256'); - expect(entry.spec.content.payloadHash?.value).toBe( - crypto.hash(sigBundle.dsseEnvelope.payload).toString('hex') + expect(entry.spec.proposedContent).toBeTruthy(); + expect(entry.spec.proposedContent?.envelope).toEqual( + JSON.stringify(envelopeToJSON(sigBundle.dsseEnvelope)) ); - expect(entry.spec.content.hash).toBeTruthy(); - expect(entry.spec.content.hash?.algorithm).toBe('sha256'); - - // This hard-coded hash value helps us detect if we've unintentionally - // changed the hashing algorithm. - expect(entry.spec.content.hash?.value).toBe( - '37d47ab456ca63a84f6457be655dd49799542f2e1db5d05160b214fb0b9a7f55' + expect(entry.spec.proposedContent?.verifiers).toHaveLength(1); + expect(entry.spec.proposedContent?.verifiers[0]).toEqual( + enc.base64Encode(publicKey) ); }); }); @@ -123,7 +99,7 @@ describe('toProposedEntry', () => { }; it('return a valid ProposedEntry entry', () => { - const entry = toProposedEntry(sigBundle, publicKey); + const entry = toProposedEntry(sigBundle, publicKey, 'intoto'); assert(entry.apiVersion === '0.0.2'); assert(entry.kind === 'intoto'); @@ -174,30 +150,52 @@ describe('toProposedEntry', () => { }, }; - it('return a valid ProposedEntry entry', () => { - const entry = toProposedEntry(sigBundle, publicKey); - - assert(entry.apiVersion === '0.0.2'); - assert(entry.kind === 'intoto'); - - // Check to ensure only the first signature is included in the envelope - const e = entry.spec.content.envelope; - expect(e?.signatures).toHaveLength(1); - expect(e?.signatures[0].keyid).toEqual( - sigBundle.dsseEnvelope.signatures[0].keyid - ); - expect(e?.signatures[0].sig).toEqual( - enc.base64Encode( - sigBundle.dsseEnvelope.signatures[0].sig.toString('base64') - ) - ); - expect(e?.signatures[0].publicKey).toEqual(enc.base64Encode(publicKey)); + describe('when asking for an intoto entry', () => { + it('return a valid ProposedEntry entry', () => { + const entry = toProposedEntry(sigBundle, publicKey, 'intoto'); + + assert(entry.apiVersion === '0.0.2'); + assert(entry.kind === 'intoto'); + + // Check to ensure only the first signature is included in the envelope + const e = entry.spec.content.envelope; + expect(e?.signatures).toHaveLength(1); + expect(e?.signatures[0].keyid).toEqual( + sigBundle.dsseEnvelope.signatures[0].keyid + ); + expect(e?.signatures[0].sig).toEqual( + enc.base64Encode( + sigBundle.dsseEnvelope.signatures[0].sig.toString('base64') + ) + ); + expect(e?.signatures[0].publicKey).toEqual( + enc.base64Encode(publicKey) + ); + + // This hard-coded hash value helps us detect if we've unintentionally + // changed the hashing algorithm. + expect(entry.spec.content.hash?.value).toBe( + '37d47ab456ca63a84f6457be655dd49799542f2e1db5d05160b214fb0b9a7f55' + ); + }); + }); - // This hard-coded hash value helps us detect if we've unintentionally - // changed the hashing algorithm. - expect(entry.spec.content.hash?.value).toBe( - '37d47ab456ca63a84f6457be655dd49799542f2e1db5d05160b214fb0b9a7f55' - ); + describe('when asking for a dsse entry', () => { + it('return a valid ProposedEntry entry', () => { + const entry = toProposedEntry(sigBundle, publicKey, 'dsse'); + + assert(entry.apiVersion === '0.0.1'); + assert(entry.kind === 'dsse'); + + expect(entry.spec.proposedContent).toBeTruthy(); + expect(entry.spec.proposedContent?.envelope).toEqual( + JSON.stringify(envelopeToJSON(sigBundle.dsseEnvelope)) + ); + expect(entry.spec.proposedContent?.verifiers).toHaveLength(1); + expect(entry.spec.proposedContent?.verifiers[0]).toEqual( + enc.base64Encode(publicKey) + ); + }); }); }); }); @@ -214,7 +212,7 @@ describe('toProposedEntry', () => { }; it('return a valid ProposedEntry entry', () => { - const entry = toProposedEntry(sigBundle, publicKey, 'dsse'); + const entry = toProposedEntry(sigBundle, publicKey); assert(entry.apiVersion === '0.0.1'); assert(entry.kind === 'dsse'); diff --git a/packages/sign/src/witness/tlog/entry.ts b/packages/sign/src/witness/tlog/entry.ts index 61e17075..c721ccc0 100644 --- a/packages/sign/src/witness/tlog/entry.ts +++ b/packages/sign/src/witness/tlog/entry.ts @@ -28,15 +28,15 @@ export function toProposedEntry( content: SignatureBundle, publicKey: string, // TODO: Remove this parameter once have completely switched to 'dsse' entries - entryType: 'dsse' | 'intoto' = 'intoto' + entryType: 'dsse' | 'intoto' = 'dsse' ): ProposedEntry { switch (content.$case) { case 'dsseEnvelope': - // TODO: Remove this conditional once have completely switched to 'dsse' entries - if (entryType === 'dsse') { - return toProposedDSSEEntry(content.dsseEnvelope, publicKey); + // TODO: Remove this conditional once have completely ditched "intoto" entries + if (entryType === 'intoto') { + return toProposedIntotoEntry(content.dsseEnvelope, publicKey); } - return toProposedIntotoEntry(content.dsseEnvelope, publicKey); + return toProposedDSSEEntry(content.dsseEnvelope, publicKey); case 'messageSignature': return toProposedHashedRekordEntry(content.messageSignature, publicKey); }