Skip to content

Commit

Permalink
add legacyCompatibility to sign/attest functions (#1287)
Browse files Browse the repository at this point in the history
Signed-off-by: Brian DeHamer <[email protected]>
  • Loading branch information
bdehamer authored Oct 10, 2024
1 parent d758abc commit 91c8478
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-mangos-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'sigstore': major
---

Updates the `sign` and `attest` functions so that they generate v0.3 Sigstore bundles by default. To continue generating v0.2 bundles, use the new `legacyCompatibility` flag.
6 changes: 4 additions & 2 deletions packages/client/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# sigstore &middot; [![npm version](https://img.shields.io/npm/v/sigstore.svg?style=flat)](https://www.npmjs.com/package/sigstore) [![CI Status](https://github.com/sigstore/sigstore-js/workflows/CI/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/ci.yml) [![Smoke Test Status](https://github.com/sigstore/sigstore-js/workflows/smoke-test/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml)
# sigstore &middot; [![npm version](https://img.shields.io/npm/v/sigstore.svg?style=flat)](https://www.npmjs.com/package/sigstore) [![CI Status](https://github.com/sigstore/sigstore-js/workflows/CI/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/ci.yml) [![Smoke test](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml/badge.svg)](https://github.com/sigstore/sigstore-js/actions/workflows/smoke-test.yml)

A JavaScript library for generating and verifying Sigstore signatures. One of
the intended uses is to sign and verify npm packages but it can be used to sign
Expand All @@ -12,7 +12,7 @@ and verify any file.

## Prerequisites

- Node.js version >= 16.14.0
- Node.js version >= 18.17.0

## Installation

Expand Down Expand Up @@ -161,6 +161,7 @@ necessary to verify the signature.
- `tlogUpload` `<boolean>`: Flag indicating whether or not the signature should be recorded on the Rekor transparency log. Defaults to `true`.
- `identityToken` `<string>`: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
- `identityProvider` `<IdentityProvider>`: Object which implements `getToken: () => Promise<string>`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
- `legacyCompatibility` `<boolean>`: Flag indicating whether to enable legacy compatibility mode. When set to `true`, the returned bundle will use the Sigstore v0.2 bundle format. When unset or `false`, the returned bundle will be v0.3 or greater.

### attest(payload, payloadType[, options])

Expand All @@ -177,6 +178,7 @@ as well as the verification material necessary to verify the signature.
- `tlogUpload` `<boolean>`: Flag indicating whether or not the signed statement should be recorded on the Rekor transparency log. Defaults to `true`.
- `identityToken` `<string>`: The OIDC token identifying the signer. If no explicit token is supplied, an attempt will be made to retrieve one from the environment. This config cannot be used with `identityProvider`.
- `identityProvider` `<IdentityProvider>`: Object which implements `getToken: () => Promise<string>`. The supplied provider will be used to retrieve an OIDC token. If no provider is supplied, an attempt will be made to retrieve an OIDC token from the environment. This config cannot be used with `identityToken`.
- `legacyCompatibility` `<boolean>`: Flag indicating whether to enable legacy compatibility mode. When set to `true`, any record written to the Rekor transparency log will use the "intoto" record type and the returned bundle will use the Sigstore v0.2 bundle format. When unset or `false`, the "dsse" Rekor type will be used and the returned bundle will be v0.3 or greater.

### verify(bundle[, payload][, options])

Expand Down
39 changes: 38 additions & 1 deletion packages/client/src/__tests__/sigstore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('sign', () => {
});
});

describe('signAttestation', () => {
describe('signAttestation (legacy)', () => {
const payload = Buffer.from('Hello, world!');
const payloadType = 'text/plain';

Expand All @@ -92,6 +92,7 @@ describe('signAttestation', () => {
rekorURL,
tsaServerURL: tsaURL,
identityProvider: idp,
legacyCompatibility: true,
};
const bundle = await attest(payload, payloadType, options);
expect(bundle).toBeDefined();
Expand All @@ -114,6 +115,42 @@ describe('signAttestation', () => {
});
});

describe('signAttestation (non-legacy)', () => {
const payload = Buffer.from('Hello, world!');
const payloadType = 'text/plain';

beforeEach(async () => {
await mockFulcio({ baseURL: fulcioURL });
await mockRekor({ baseURL: rekorURL });
await mockTSA({ baseURL: tsaURL });
});

it('returns the signed bundle', async () => {
const options: SignOptions = {
fulcioURL,
rekorURL,
tsaServerURL: tsaURL,
identityProvider: idp,
};
const bundle = await attest(payload, payloadType, options);
expect(bundle).toBeDefined();
expect(bundle.dsseEnvelope?.payloadType).toBe(payloadType);
expect(bundle.dsseEnvelope?.payload).toBe(payload.toString('base64'));
expect(bundle.dsseEnvelope?.signatures).toHaveLength(1);

expect(bundle.verificationMaterial.certificate).toBeDefined();

expect(bundle.verificationMaterial.tlogEntries).toHaveLength(1);
expect(bundle.verificationMaterial.tlogEntries[0].kindVersion?.kind).toBe(
'dsse'
);

expect(
bundle.verificationMaterial.timestampVerificationData?.rfc3161Timestamps
).toHaveLength(1);
});
});

describe('#verify', () => {
let tufRepo: ReturnType<typeof mocktuf> | undefined;
let tufOptions: VerifyOptions | undefined;
Expand Down
5 changes: 3 additions & 2 deletions packages/client/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type SignOptions = {
rekorURL?: string;
tlogUpload?: boolean;
tsaServerURL?: string;
legacyCompatibility?: boolean;
} & FetchOptions;

export type VerifyOptions = {
Expand Down Expand Up @@ -95,7 +96,7 @@ export function createBundleBuilder(
case 'dsseEnvelope':
return new DSSEBundleBuilder({
...bundlerOptions,
certificateChain: true,
certificateChain: options.legacyCompatibility,
});
}
}
Expand Down Expand Up @@ -170,7 +171,7 @@ function initWitnesses(options: SignOptions): Witness[] {
witnesses.push(
new RekorWitness({
rekorBaseURL: options.rekorURL,
entryType: 'intoto',
entryType: options.legacyCompatibility ? 'intoto' : 'dsse',
fetchOnConflict: false,
retry: options.retry ?? DEFAULT_RETRY,
timeout: options.timeout ?? DEFAULT_TIMEOUT,
Expand Down

0 comments on commit 91c8478

Please sign in to comment.