-
Notifications
You must be signed in to change notification settings - Fork 702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question or Feature Request] Make bearer token location in browser storage configurable #2253
Comments
Hi there, just a bit of background / clarification (in case it's not obvious)
This is only for demo's or similar where a K8s service account token is provided directly to Kubeapps and used for authentication. We don't recommend this for anything other than demo (nor storing any credential client side generally). When using OIDC, we have the upstream proxy ( So it's not clear to me why you need any frontend code at all for your use-case? Your auth service can set whatever Let me know if I've missed something or if that works. I've already been keen to remove the now demo-only service token support in the frontend due to the security implications, so if your use-case is that the user will enter the web hook token into the UI, I'd not be so keen - but still happy to discuss. If on the other hand it's coming from your authn service, it should be able to be kept within your servers as above (ie. client code never sees it, as we do for oidc). Hope that helps! |
Thanks a lot for your extensive response! I really appreciate you taking the time.
This sounds interesting but I'm not sure I'm following... In my example, Does this make sense? |
@absoludity in other words, if we set a cookie for domain |
Nope, I mean, even if the cookie header was sent, webhook authentication works with bearer tokens ( Technically yes, if you set a non httpOnly cookie, the dashboard could do that, but I would not be doing that if I were you from a security pov: it means you've got your credential for accessing the cluster being sent out to people's (insecure) browsers. For session cookies you should always be using an httpOnly cookie (which client code running on the browser cannot even access, by design). Secondly, your session cookie should either be a unique identifier only, or an encrypted credential which gets switched for the unencrypted credential by oauth2-proxy or similar once within your internal network, for similar reasons (so all that the client ever sees is a unique identifier that they can't do anything with). Stepping back to your original question (and apologies in advance if I'm misunderstanding)
I assume this is for authenticating requests to your PaaS, not for user authentication of your web app - ie. you still need users to login and be assigned some access token which can later be used with your backend authentication.
You don't need to write the IdP used for user authentication though do you? Just use one of the many available (or your companies existing SSO, assuming it's oauth2 compliant)?
(yes, never do this, it's for demos only these days :) )
So for the authentication with your cluster, yes you can either use the existing OIDC support in k8s, or create your own webhook token auth server, but either way you'll want your session cookie converted to a bearer token only once the request gets within your network. This is exactly what oauth2-proxy does (storing the credential - jwt and/or non-jwt access token - and setting a cookie then switching the cookie for the credential when requests enter the internal network). If that's not an option, then yes, the dashboard could be updated to do what you're asking, but there's a serious security risk IMO (the same reason we only recommend the token auth for demos). |
@absoludity OK, thanks once again for the thoughts & feedback, it's very much appreciated 😅
I assume you are referring to things like Auth0, Keycloak, etc.? We looked into these and are hesitant to go the OAuth route until we are quite sure we need it. And "company's existing SSO" - well, we are building it right now! 😆 I think what I am envisioning is a ... non-OAuth2 auth proxy? Such a proxy could e.g. check for an In other words, I am OK with trusting a session ID stored in an I believe I understand the flow I want, I am just not sure how to configure/use kubeapps to make this work... but please let me know if this is a terrible idea or if I'm missing something! |
No problem :)
Or, depending whether your company uses Microsoft products or Google products, Azure Active directory, or Google authentication (or any of the myriad of providers, if your company is already using one).
Hmm, you need some way of enabling your users, employees, clients to authenticate - not sure what you would use for SSO if not some OAuth identity provider.
Ok, well writing your own SSO (or implementing your own identity provider) is a pretty serious venture. Hope you've got the resources for that!
So if you have the rest of it sorted out, then yes, that should be trivial and not even require changes in Kubeapps, just with some nginx config, eg: https://stackoverflow.com/a/39353517 That writes an |
FYI our use case is to expose this to customers, not developers/internal users (although really both should be supported). So while we want to give users the ability to e.g. login/signup with say GitHub or GitLab (OAuth "client" from our perspective), we're not quite convinced we need to implement OAuth in our auth server(s) and issue JWTs, etc.
My understanding of SSO is that it is not inherently dependent on OAuth so, why do you say this? We want the simplest version of SSO (from Wikipedia):
Regarding the proxy conversation...
Yes, this is what I think makes sense for us, but where would this proxy sit? Between the kubeapps frontend and the kubeapps backend? Or between the kubeapps backend and our k8s API? Other? I don't see where I could insert a proxy into the kubeapps design and am feeling stupid but it's probably because it's getting quite later here |
Right, you might not need OAuth, but you need your users to sign in securely so that the end result is that a cookie is set on the client. At that point, sure you can roll your own, or better, use some simple but trusted package to manage logins, or use an existing (free service). I didn't mean that you can only use OAuth, I just wasn't understanding why you wouldn't.
Yep, I just wouldn't consider rolling my own SSO service in most cases. Sorry, I didn't mean to derail the conversation in that direction. You know your requirements :)
Heh no, this stuff can be confusing to work through, but worth getting right :) So I don't think you need to insert a proxy as you already have one in the nginx running on the kubeapps frontend deployment. You can test it out by manually editing the frontend configmap with:
If you can get what you want working with that, happy to update the Kubeapps chat to have an option for some additional config for the frontend nginx reverse proxy. |
Oh my goodness, this is really great news - I didn't realize we had an NGINX instance at our behest for this! @absoludity thank you again for taking the time, I will update you once we finalize our auth strategy here 😄 .
I agree that when phrased like that it does sound daunting but, having done a bunch of research at this point, I don't see how SSO "achieved over IP networks using cookies" (to quote the Wiki again) is going to be more difficult that SSO achieved using an OAuth implementation. My stance is that we will know when OAuth/OIDC is the tool we need and it will be painfully obvious that we are missing an auth strategy that allows us to encode data in client-borne (as in "bearer") tokens that don't need to phone home to do authN/authZ. As an example, we have a file uploader service for our VFX platform Concierge Render that is confidential (i.e. non directly user-facing) with respect to the Concierge app servers (which is a Rails app). To perform auth for file upload requests, we pass the cookie from the browser which contains a JWT that once decoded reveals the user's UID. From that we can construct the path in the file storage node (we use cephFS) and rebuild the uploaded file chunks in the right place. IMO this is a nice, clean use of JWTs. Technically since the network request is "intra-cluster" we don't even have to do TLS, nor do we have to calculate the MAC signature on the JWT (no opportunity for any MITM attack) - so this auth strategy is much faster than phoning home/hitting a DB/hitting an internal auth API endpoint, which is appropriate since we really hammer the That said, most of our other auth needs simply won't be like this, especially as we start to fold in things like permissions (which IMO should not be sent w/ JWTs since they can change in the DB at any moment), multi-user organizations (for cloud customers signing up as companies - think like AWS/GCloud), etc. Sorry for the diatribe but there you have it, in case you were interested in some further context. |
From reading the code it seems like the The goal is to entirely bypass the above page that prompts the user to enter a token. |
Hey @absoludity I'm sure you got a notification already but, just in case, I wrote some (totally not working) code to hopefully benefit this conversation and clarify what I'm going for and the changes I am proposing. 😄 |
Background
We are writing a new authentication backend server for our cloud PaaS product/platform.
If we write an OIDC-compliant auth server (i.e. our own IdP), we can configure kubeapps to use this viva
oauth2-proxy
for authenticating users in a more seamless way than having them copy-paste tokens. This is all well-documented e.g. here.However, it will be much faster for us to implement a simple webhook token auth server backend instead. Moreover we aren't in love with JWTs in general and are leaning towards tried-and-true session management instead.
We intend to host kubeapps on our cloud platform's domain, e.g.
cloud.coreweave.com/apps
, so if we are able to write a cookie for this domain as part of normal user login flow oncloud.coreweave.com
, we just need a way to tell kubeapps to read some value from a cookie and use it for bearer token auth.I found these lines of code in the frontend apphttps://github.com/kubeapps/kubeapps/blob/9a7b52c6911e8d97f470677722043b3ae765037e/dashboard/src/shared/Auth.ts#L10-L12 whereby the
kubeapps_auth_token
is read out of the browser's local storage.Current Behavior
The kubeapps frontend always looks in
localStorage
for the token to authenticate requests to the kubeapps backend.Proposal
Make the choice of "in-browser token storage backend" configurable, e.g
document.cookie
instead oflocalStorage
for thekubeapps_auth_token
. That would be a simple and elegant solution to our use-case, I believe.We could write a cookie containing an opaque token for that user after they login as normal. Upon navigating to
/apps
we can render kubeapps, and kubeapps will now be configured to read from cookies (instead of local storage, the current default token location in the browser) in order to obtain the auth token to be sent w/ requests to the backend.The text was updated successfully, but these errors were encountered: