Right now, every package you download from npm is unsigned. That means you could download what you intend to one minute, and the next minute be served a compromised package with the exact same name.
This isn’t theoretical either; last weekend several commonly used packages went missing from the npm registry, seemingly without reason. After they disappeared, other people took over 9 of those package names, and in at least one case changed the package to do something else entirely.
Eventually npm restored the original packages, but for 3 hours on the weekend, every user and every build server that downloaded one of those 9 packages potentially ran or installed code that wasn’t written by any of the owners of the original packages.
As a company that uses npm to pull in dependencies for the web console of their SaaS, that’s terrifying.
Package signing isn’t a new concept. It’s been discussed since at least 2015 for Node.js, but to date, it hasn’t actually been available for npm users. Instead of waiting any longer for official support for package signing to arrive, we wrote pkgsign to support it today.
pkgsign, for signing and verifying npm packages
pkgsign is a CLI tool that uses keybase.io and PGP keys to sign and verify npm packages. When you sign a package, it hashes all files included in the package and signs the combined list of files and hashes with your private key. The content has to match exactly (so no extra files, nor deleted files are allowed).
You can install pkgsign today by following the instructions on the GitHub repository.
If you’ve got keybase and pkgsign installed, signing your package is as easy as:
pkgsign sign .
You can then publish your package as normal, and the
signature.json file that was added by pkgsign can be used to verify your package contents. (If you have prepublish or prepack lifecycle hooks that modify content, you’ll need to sign the tarball instead with
pkgsign sign tarball.tgz, and publish that).
For most individual developers, this is best way to get your packages signed and verifiable today. As a bonus, keybase allows you to connect that signature with your public presence on Twitter, Reddit and other sites, so users know the package really is signed by the right person.
Larger companies can use the support for PGP signing instead of keybase. This involves generating a PGP key, uploading the public key component to a HTTPS URL (presumably under a domain you control), then passing the private key to
To verify the current package you’re working on, and all the dependencies it depends on, run:
pkgsign verify . --full
You don’t need keybase or any additional software installed to verify package signatures.
Right now, most verifications will fail because very few of your dependencies will be signed with pkgsign (after all — this is being announced right now!) By using
--full you can see which packages are unsigned and which are trusted.
At some point we plan on adding support for “signing on behalf of”, where you can sign the content of your dependencies. As a library author this gives you the benefit of a fully signed tree for your package without having to waiting on your package dependencies to be signed, at the cost of having to use exact versions (because dependency content can not change at all without invalidating the “on behalf of” signature).
This software is very new, and hasn’t had a whole lot of battle testing yet. I’m not in any way claiming that this is a perfect solution today, but it’s a lot better than what the ecosystem has right now.
Furthermore, the dependencies of pkgsign itself aren’t yet signed, and “on behalf of” signatures aren’t available yet, so your ability to verify that pkgsign hasn’t been tampered with via a dependency is limited.
pkgsign is MIT licensed. If you think you have something to add, whether it’s features or use cases, feel free to send pull requests or submit issues over at the GitHub repository.
Now it’s up to you!
Package signing is only as good as the number of developers who adopt it. If you like the sound of pkgsign and want to show your support, adding package signatures to packages you own is a great way to do it.