Signing CPAN Releases with SigStore

Signing CPAN Releases with SigStore

At the most recent Perl Tool Chain Summit (PTS) in Vienna we decided to deprecate Module::Signature. Module::Signature has been around for a long time but it has become increasingly clear that it does not provide the security assurances that it was designed to deliver.

Dist::Zilla::Plugin::SigStore::SignRelease is a new plugin that signs your CPAN release with SigStore before uploading. SigStore uses short-lived, OIDC-issued certificates. You authenticate with Google, GitHub, or Microsoft, and cosign produces a signature bundle. No long-lived keys, no keyserver dance.

How it works

The plugin extends the Dist::Zilla plugin UploadToCPAN. During the dzil release, it:

  1. Calls cosign sign-blob on your release archive, producing a .sigstore.json bundle file.
  2. Pulls the certificate out of the bundle and verifies the signature locally before anything leaves your machine.
  3. Uploads both the tarball and the bundle to PAUSE.

SigStore also add the release and signature information to the Rekor Transparency Log. Rekor is SigStore's public append-only transparency log, and the inclusion proof is bundled into the .sigstore.json. Anyone verifying your release can confirm the signing event was publicly logged at the time it happened.

Using it

Remove the existing uploader from your Dist::Zilla configuration file (dist.ini) and add the plugin to your dist.ini:

[@Filter]
bundle = @Basic
remove = UploadToCPAN ; Do this if you use @Basic

[SigStore::SignRelease]

Non-CPAN Requirements

You'll need cosign in your PATH.

Next Steps

PAUSE doesn't verify SigStore signatures yet, and no CPAN client checks them on install.

This is opt-in transparency: the bundle ships alongside the tarball, and anyone who cares can verify it themselves.

Hopefully more support for SigStore will be developed soon. Until then signing your releases will allow them to be verified:

cosign verify-blob Your-Dist-0.01.tar.gz \
--bundle Your-Dist-0.01.tar.gz.sigstore.json \
--certificate-identity you@example.com \
--certificate-oidc-issuer https://accounts.google.com

It's a first step, towards verifiable releases in the Perl ecosystem. Try it on your next release and let me know how it goes.

12 Comments

nice!

it says it uses OIDC to authenticate users, but also that it only works with google, microsoft, and github

so… is there no way to use my own OIDC identity provider?

do we want to be tied to google and microsoft?

The main message should be that this is paralleling efforts in other repositories, such as npm and PyPl. No matter the wisdom of this particular technique, any approach is only really useful if the end user doesn't have to coordinate across potentially hundreds of these sorts of services when every provider has their own weird or bespoke thing.

The unfortunate license choice for Module::Signature made it challenging to use. No it's not "perl 5" as the metacpan page says, it is CC0 as per the pod, at least one of the pod subheadings anyway - very confusing.

However, having signed CPAN releases is a very good thing especially if there can be an established standard that the major cpan clients implement (cpanm, cpm, cpan and pause itself). More so if we can start seeing signed releases of Perl itself and core libraries.

At present, if you are concerned with supply chain integrity (and you should be) then using only perl and perl packages from your distribution (assuming they are all signed) is perhaps the only viable approach. Or mirroring every repo for every package you use (including perl itself) then building from those mirrors - whilst curating every regular update of those mirrors.


The license is just one issue with Module::Signature; it also suffered that the signature was included inside the tarball, so it had to decide what it was actually signing and so would the verifier. Among other issues that I'm not expert enough to recount, which weakened its usefulness in providing verification. This plugin avoids the first issue by uploading the signature as a file separate from the tarball, so it's already a significant improvement.

I can think of two things needed to really make this a complete solution: options for identity provider which suffice for any potential user, and the ability to verify the trust chain all the way back to the author so it can't be sidestepped by an attacker uploading their own signature (which largely needs some form of coordination in PAUSE itself).

If PAUSE could provide (pardon the pun) an identity provider service that this could utilize, that seems like it would make a nice closed loop of trust. PAUSE mostly only gets significant overhauls at a PTS though :)

This discussion seems healthy and there appears to be alot of alignment already.

Leave a comment

About Timothy Legge

user-pic FOSS developer who has been scratching various itches for many years.