Skip to content

npm/provenance

Repository files navigation

provenance

Details on npm provenance

Packages

Demo: Generating signed SLSA provenance

GitHub Actions

.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

Publishing with provenance

Overview

  • npm/cli
  • 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

Server-side provenance verification and proof

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 uploaded package.json matches what's in the signing certificate Source 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.

Verifying attestations with npm audit signatures

Overview

  • 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

Viewing provenance on npmjs.com

Compatibility

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

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)

Adding support for new CI vendors

Updating the SLSA predicate

Resources