Details on npm provenance
@npmcli/provenance-cli
- Command line interface for generating SLSA provenance on supported CI/CD vendors.@npmcli/generate-provenance
- Library for generating SLSA provenance on supported CI/CD vendors.@npmcli/verify-provenance
- Library for verifying SLSA provenance from supported CI/CD vendors.
.github/workflows/provenance.yml
name: SLSA Provenance
on:
workflow_dispatch:
permissions:
id-token: write
jobs:
provenance:
name: Generate signed SLSA provenance with Sigstore
runs-on: ubuntu-latest
steps:
- name: Setup node
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4
- name: Generate dummy package
run: echo "hello world" > pkg && tar -czvf pkg.tgz pkg
- name: Generate provenance statement with package as attestation subject
run: npx @npmcli/provenance-cli generate pkg.tgz -o provenance-statement.json
- name: Sign provenance statement
run: npx @sigstore/cli attest ./provenance-statement.json -o provenance.sigstore.json
- name: Verify provenance statement (TODO: Verify source identity)
run: npx @sigstore/cli verify provenance.sigstore.json
- name: Upload artifact
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
with:
name: provenance-sigstore.json
path: provenance.sigstore.json
- npm/cli
- Generate provenance statement
- Publish: Upload the signing certificate, signed provenance and package to the npm registry
- sigstore/sigstore-js
- Sign package
- Request workflow identity (OIDC ID token) from CI/CD
- Create a temporary public/private key pair
- Send a proof of private key possession, ID token and public key to Fulcio
- Fulcio verifies and returns a signing certificate valid for 10 mins
- Sign the provenance statement and uploads it to Rekor and deletes the keys
npm performs server-side verifications and integrity checks on the provenance bundle before accepting the publish:
- Validate the
Issuer
extension in the signing cert is supported - Validate provenance was generated on a cloud-hosted runner by comparing the
Runner Environment
extension in the signing cert against allowed values - Validate provenance was generated on a public repository/project by comparing the
Source Repository Visibility At Signing
extension in the signing cert against allowed values - Verify extensions in the signing certificate (non-falsifiable) match what's in the SLSA provenance statement (generated in the npm/cli and falsifiable by modifying the env vars during build)
- Verify provenance was signed and uploaded to Sigstore:
sigstore.verify(provenanceBundle)
- Downloads the latest root certificate and public keys for Sigstore public good by using tuf-js
- Verify the published package name, version (PURL) and tarball
sha-512
matches what's in the signed provenance statement subject - Verify the
repository
/repository.url
in the uploadedpackage.json
matches what's in the signing certificateSource Repository URI
extension
When verification is succesful npm attests the publish with by signing a publish attestation. This proves the registry accepted the published version /w proof on Rekor to keep the registry honest.
Public signing keys for the signed publish attestation
are distributed via the public Sigstore Trust Root in a target that matches the registry hostname: registry.npmjs.org.
This means another npm registry can distribute public keys using the same hostname scheme and these will be discovered by the npm cli during verification.
- npm/cli
- Audit command
- Invokes
sigstore.verify
on each downloaded bundle - Verify the attestation matches the installed package name, version and tarball by comparing the in-toto attestation subject name and digest
- Verify that the registry accepted the publish by an authorized user/token by verifying at least on attestation using a trusted public key from the sigstore trust-root
- sigstore/root-signing
- sigstore/sigstore-js
- sigstore.verify
- Update Sigstore trusted root using tuf-js
- Verify artifact signature using public key in signing certificate
- Verify signing certificate was issued by Sigstore trusted root certificate
- Verify Fulcio signed the certificate values/extensions at a given time (SCT)
- Verify Rekor received the signed attestation while the signing certificate was valid
Summary of Sigstore provenance verification support in npm registry
- The registry supports verifying sigstore v0.1 and v0.2 bundles generated by sigstore-js 1.0+ (from npm cli 9.5.0+)
- Support verifying both slsa v0.2 and v1.0 provenance predicate's from GHA and slsa v0.2 provenance predicates from GitLab
- Verify the latest version of the Fulcio Signing Certificate as any client sigstore combo will always get the latest one from Fulcio
- See list of current Fulcio signing cert extensions
The following table documents which combinations of Sigstore bundle versions, sigstore
client versions, npm
CLI versions and SLSA predicate versions that are supported by the npm registry.
sigstore | 1.0..1.5 | 1.6 | 1.7..2.0 | 2.1 |
---|---|---|---|---|
npm | 9.5.0..9.6.7 | 9.7.2 | 9.8.0 | 10.0.0 |
Bundle Version | ||||
v0.1 | ✅ | ✅ | ✅ | ✅ |
v0.2 | ✅ | |||
SLSA Predicate | ||||
v0.2 (GHA) | ✅ | ✅ | ||
v1.0 (GHA) | ✅ | ✅ | ||
v0.2 (GitLab) | ✅ | ✅ | ✅ |
- npm/cli
- Generate a SLSA v1.0 (as of writing) provenance statement during build, see example for GHA/GitLab
- Check pre-requisites are met for provenance generation, see example
- See example for added gitlab support
- sigstore/sigstore-js
- Mint an ID token, see example for GHA/GitLab
- See example for added gitlab support
- Talk: Build provenance for package registries
- Blog: Introducing npm package provenance
- Docs: Generating provenance statements
- Article: Build Provenance for All Package Registries
- Example: Publishing npm package with provenance
- RFC: Link npm packages to the originating source code repository and build