Thanks for sharing this pre-RFC! I'm one of the maintainers of
sigstore-python and I'm actively working with the Python community to get Sigstore integrated into PyPI, so I have some design feedback based on our experience there
Identity/scope of verification
Anybody can sign for anything in Sigstore, so every Sigstore verification operation needs to be performed modulo a specific identity (or set of identities). In particular, it isn't enough to just verify that the signature and certificate are valid and consistent with the transparency log, since
email@example.com can sign for
serde's crates just as easily as
I think this is alluded to in the pre-RFC, with this language:
- Email of Owner - retrieved as part of identity/GitHub lookup with email scope
However, this probably won't be sufficient on its own: emails are only one form of identity in Sigstore (GitHub Actions and other CI providers can also produce ephemeral OpenID connect identities, encoded as URLs). Moreover, just the identity string itself is not enough -- verification also requires establishing that the IdP attesting to the identity is the one expected (per If `--cert-email` is provided, `--cert-oidc-provider` should be required (verification) · Issue #1947 · sigstore/cosign · GitHub),
The latter problem might not be a significant issue for Rust, since it seems like GitHub is the intended MVP target and simply requiring all identities to come from
https://github.com/login/oauth might be sufficient. But it's something to keep in mind for future expansion, and both should probably be addressed in the RFC to ensure that e.g. CI publishing workflows can also sign for crates without requiring manual signing operations
At the moment, the pre-RFC specifies the following verification flow:
In this flow, Rekor (the transparency log) is accessed on each verification operation. This isn't a problem in terms of Rekor itself (it was designed for this!), but it might be a problem for (1) privacy conscious users, who wouldn't like the transparency log to know roughly when they're fetching dependencies, and (2) corporate users who might have firewall or other network rules that rewrite
crates.io to a local mirror and forbid other network traffic.
Sigstore has accommodations for these use cases, in the form of offline Rekor bundles and Sigstore bundles, the latter being a replacement for the former.
When using a bundle instead of an online lookup, the threat model changes slightly (the verification entails verifying a signed promise of inclusion by the transparency log, rather than a proof of inclusion), but at the benefit of requiring no connection to the log whatsoever.
It probably makes sense for
cargo to support a variant of this flow, possibly with some kind of
--offline flag (that's what
sigstore verify uses). When passed,
cargo should additionally retrieve the Rekor bundle from the index, and use that rather than performing an online transparency log check.
(More generally, the need to special-case bundle retrieval will be obviated once Sigstore bundles are stabilized, since the index will only have to host one additional file rather than separate files for the cert, signature, and Rekor bundle. Once that happens,
--offline could be as simple as using the embedded Rekor promise.)
Verifying on the index as well?
This is more speculative, but something (IMO) worth thinking about: in addition to having
cargo verify signatures on client endpoints during package retrieval/install, it might be worth performing signature verification on the package index itself (i.e.
Doing so has a few advantages:
- Catching programmer/publisher errors earlier: if users can configure their packages as requiring signatures, the index and
cargo publish can coordinate to reject uploads that don't include a signature. Similarly, if users can configure a trusted list of identities for their packages, the index and client can coordinate to reject uploads that are signed by the wrong identity.
- Visual identity: lots of developers check
crates.io for a package's links and statistics before downloading. Having a little green checkmark or similar can serve as a visual indicator that the package is signed, which users can then make value judgments about.
Once again: thanks so much for making this pre-RFC! I think Sigstore in Rust is extremely promising, and I'm excited to see what the community thinks