fulcio
fulcio copied to clipboard
Support for a non-public client?
The OIDC flow used by fulcio / cosign appears to be limited to public OAuth2 clients. That is, cosign
is both the OAuth2 client and the user client, acquires the OIDC ID token, and sends it to fulcio
(which is the relying party).
This is a bit limiting as it limits fulcio to issuers that support public clients (and PKCE).
Was there ever any consideration of alternate OIDC setups? For example, if fulcio
itself is the OIDC client, then it can maintain confidentiality and use a wider range of issuers.
Thanks!
Could you explain the use case a bit more? I'm not sure I fully understand it, but it sounds like something we'd like to support.
Sure! For the academic community, the relevant identity is not the Google account but rather the ORCID; associating a container image with a random Google account has no impact in the community whereas the ORCID (example: https://orcid.org/0000-0003-2981-3809) is associated with the papers I publish and the grants I write -- that's a real currency.
However, like a number of identity providers, it doesn't appear that ORCID's OIDC issuer supports a public OIDC client (e.g., client ID only) but requires a confidential client (e.g., client ID + secret).
As another example, CILogon provides an OIDC endpoint (see https://www.cilogon.org/oidc) which does support a public client -- but only for anonymized identifiers (anonymous identifiers aren't so useful for signing). If Fulcio could support a confidential client, CILogon can release other identifiers (such as the ePPN; https://www.educause.edu/fidm/attributes) that are more valuable to the community.
Hope this helps!
Ah I see. cc @bobcallaway. I think we do actually support this flow because Fulcio uses a hosted Dex instance for the actual token exchanges. We'd be able to configure a real client secret there.
Yes, there's no problem with configuring a client secret in Fulcio itself (in fact, I started down this route, hoping to open a PR instead of an issue!) -- but part of the problem is the auth between cosign<->Fulcio. In the current setup, cosign
is an OAuth2 client and an end-user application whereas Fulcio is simply a relying party. To make cosign
only an end-user application (and make Fulcio the OAuth2 client), one would need a different API to bootstrap the trust.
So, it was a tough decision of where to even open this issue -- to support non-public clients, you'd need a coordinated change between cosign and Fulcio. That's what make this one tough!
https://dexidp.io/docs/using-dex/ has a decent visualization of the two approaches; right now, we're following the approach described in https://dexidp.io/docs/using-dex/#consuming-id-tokens where the client app (cosign
) fetches the token and then passes it to the backend service (fulcio
). We initially went down this path for two reasons:
- Keep fulcio as simple as possible and avoid re-implementing a full OIDC server inside of Fulcio
- Minimize state required to be maintained in fulcio
We can implement https://dexidp.io/docs/using-dex/#requesting-an-id-token-from-dex - but as @bbockelm notes we'd need to adapt the auth design to accommodate this. I'm working on a write up for this, although it is taking longer than I'd like due to other interruptions.
Yes, I noticed that the current design has the clever side-effect of making fulcio stateless. I'd say that's a Good Thing.
However, it should be possible to do the device flow stateless as well provided there's a shared secret between the different instances; you can basically encode this as an encrypted state passed back to the client (the mod_auth_oidc
or whatever-it's-called module in apache takes this approach to maintaining oidc state IIRC).
@bobcallaway - as you point out, it gets dangerously close to having a full-fledged OIDC client in fulcio. Then again, there's basically one in in cosign right now..