Description
Most package pages on the npm registry have a link to a source repository, but this information isn’t verified and doesn’t point at any specific commit. With the code explorer you can view the contents of a package before you install it, but this doesn’t help you determine where it came from.
What we need is a way to draw a direct line from the npm package back to the exact source code commit from which it was derived. Much like an art historian tracking the chronology of ownership for a painting, we need a statement of provenance for a package which provides a verifiable record of the originating source and the build steps which were used to assemble the final artifact.
How do we ensure the compiled code published to NPM is the same that has been generated from building it by hand? There are two ways:
- Store compiled JS code in the repository. Cons: Messes-up diffs, git logs. A huge pain.
- Use publicly verifiable transparency logs and CI. NPM started providing it in Apr 2023! The blog post.
Check out bottom of README of https://www.npmjs.com/package/micro-eth-signer, there's new section:
Steps I took:
- Create granular NPM access token. It's granular, meaning, it's limited to specific packages and can't touch anything else.
- Add this
NPM_PUBLISH_TOKEN
to GitHub repository secrets. - Add publish-npm.yml to .github/workflows for GitHub Actions CI.
- Create new GitHub Release, by hand.
What happened immediately after step 4:
- GH CI ran an action that followed steps specified in publish-npm.yml.
- It set up a VM, installed node.js of specific version, executed
npm install
, executenpm run build
- It published the output to NPM
- It added signed logs to append-only ledger, which allows to verify the build was done properly
This was done manually - but I see our monorepo uses some automated way to generate github releases. It can be combined with software like changesets, which will automatically generate pull requests. Take a look at how sigstore-js did it.