cosign
cosign copied to clipboard
FR: offline mode
COSIGN_EXPERIMENTAL was introduced AFAICT for two reasons:
- The Sigstore idea, interface, and implementation were still experimental
- The Sigstore infrastructure wasn't reliable/didn't have guarantees.
So to start, anything that touched Sigstore infrastructure (TUF roots, Fulcio, Rekor) was gated: users needed to set COSIGN_EXPERIMENTAL=1 to use them.
Over time, we've blurred the line a little; without turning on experimental mode:
- You can pass a Rekor bundle and cosign will check it.
- To do that, you need the Rekor public key, which you get via TUF (this goes over the network!)
- Similarly, you can provide a cert signed by Fulcio, and cosign will check it against Fulcio's key
- It gets that key via TUF
There's a question about "what is the point of cosign verify-blob without COSIGN_EXPERIMENTAL but with a provided certificate?"
I don't want to answer that, at least not here. It's hopefully going to be an obsolete question soon: we're relatively comfortable with the idea of Sigstore, and we're targeting general availability (GA) for the infrastrcucture soon: https://github.com/sigstore/fulcio/issues/766 and https://github.com/sigstore/rekor/issues/1005 . But, at least some folks have been deliberately not providing this flag to indicate "don't try to hit the network." That's sort-of what it does right now: "I don't try to query Rekor/Fulcio, but I know about them, and also I'll get their keys via TUF."
That suggests to me that, post-dropping-COSIGN_EXPERIMENTAL, there should be some mechanism to verify offline. Maybe a --offline flag, or even a verify-offline command (which is nice because now we can only show users the relevant flags). If we do that, we probably want to have some requirement on how out-of-date your TUF roots can be (maybe user-configurable?) and instructions on how to grab them from cosign initialize.
+1 to an offline flag! Here's a copy paste of a comment I left on a doc when we were looking into the Cosign CVE:
With no flag, I'd propose the behavior be:
- Default to fetching from Rekor without any flags
- To avoid a call to Rekor, either --- provide a bundle --- add a flag explicitly opting out of the rekor call
+1 to that as the default behavior.
Then, the additional changes for an offline mode:
- use cached TUF state (after checking their age), which gives you Rekor/Fulcio root certs
- fail the command immediately if the bundle or opt-out flag isn't provided
- we never hit Fulcio in verification anyway AFAICT (though maybe eventually we should check the CT log by default unless an SCT is provided embedded in the cert)
I think that covers it?
Additional note: we need to give more guidance about offline settings, especially w/r/t TUF (do you mirror it? do you risk stale root certs?). I think this documentation would be really valuable.
@asraa's design doc for the Sigstore TUF client also mentioned supporting offline TUF. IIRC it was configurable how to handle expired metadata.
this may be relevant for the discussion here too: https://github.com/theupdateframework/go-tuf/pull/397
cc @priyawadhwa
For reference, I''ve been trying to figure out a good options for sigstore-python (mostly in context of TUF): https://docs.google.com/document/d/1IEVxgCsmLJNiAwdTFQ4aMvmGHJikmI_iOEHGpt8fIe8 (comments welcome)
My conclusions so far:
- an explicit
--offlinemode in a verifying sigstore client should still preferably use cached TUF metadata to verify the trust root that it has cached (even if this is not strictly an operation TUF spec defines). Using an unverified cached trust root may not be the worst thing in the world but likely makes client side compromise a little easier - IMO it is not feasible to build good UX while still respecting TUF expiry dates: it's not ok if the client verifies fine today but fails tomorrow because of metadata expiry
- so a good
--offlinemode for a sigstore verifying client requires the TUF implementation to have a "offline, non-expiring" mode as well - would be good to get these details defined in both TUF and sigstore client specs -- but they are client implementation details so I don't see harm in experimentation before that happens
I plan to finish an existing attempt at making that "offline, non-expiring" mode available in python-tuf.