-
Notifications
You must be signed in to change notification settings - Fork 893
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
proposal: Uniform way for handling JWTs #2748
proposal: Uniform way for handling JWTs #2748
Conversation
72342a4
to
44f5f39
Compare
4bfdcd8
to
0121ae8
Compare
The general approach looks good, although i did not check the technical details yet. |
Hey, this is the continuation of my thoughts from #2747 (comment). In general, I like this approach. In the comment linked above, I mentioned that I'd personally vote for not removing implementation of JWTs in Kubeflow components but after some thoughts over the weekend, I don't emphasize that so much right now. While I personally would love Kubeflow to be natively supporting JWTs, I understand that we have to take into account the balance between functionality and maintenance/development and offload whatever possible. With this in mind, if you decide to drop JWT implementation from kubeflow components and just rely on the
I also mentioned that I'd prefer to specify
And then to continue some other thoughts:
|
Thanks for the review @kromanow94! To avoid answering multiple parts in the same message, ending in big messages, could you provide also the above points as concrete comments on the proposal so we keep the discussions focused/separate? https://github.com/kubeflow/manifests/pull/2748/files |
### Implementation | ||
The technical details for the above proposal translate to the following | ||
1. Common Kubeflow manifests, for all components, for configuring Istio for supporting multiple issuers ([Dex](https://github.com/kubeflow/manifests/blob/v1.9-branch/common/oidc-client/oauth2-proxy/components/istio-external-auth/requestauthentication.dex-jwt.yaml) and [K8s-m2m](https://github.com/kubeflow/manifests/blob/v1.9-branch/common/oidc-client/oauth2-proxy/components/istio-m2m/requestauthentication.yaml)), via `RequestAuthentication` objects | ||
2. `AuthorizationPolicy` objects of components, for allowing access from Istio IngressGateway, will need to be extended for also requiring a JWT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May I suggest to drop the requirement to allow access only from Istio IngressGateway? AFAIR, this was a security concern from the past so the requests are always going through the EnvoyFilter
. We don't use EnvoyFilter
anymore and limiting access to requests only going through Istio IngressGateway doesn't bring any more security at this point and just makes the setup more complicated in my opinion.
If we only allow traffic to backends that have a trusted principal in requests (for the principal to be trusted and have it available to use in AuthorizationPolicy
, it must be configured through the RequestAuthentication
), there is no risk of trusting JWT/Issuer from unknown source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
" AuthorizationPolicy
objects of components, for allowing access from Istio IngressGateway, must be adjusted to enforce the presence of a JWT"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe
"AuthorizationPolicy
objects of KF Components have to be adjusted to allow access only when a trusted JWT is present in the Authorization: Bearer <Token>
header. We no longer have to enforce access only through istio-ingressgateway
."
- from: | ||
- source: | ||
principals: | ||
- cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account | ||
requestPrincipals: # new! Require JWT | ||
- '*' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this rule allows accessing the specific endpoint only if the request went through the istio-ingressgateway and contains a trusted principal.
Can we just leave it like in the suggestion below? It would lower the coupling with this specific istio gateway.
Arguments in favor:
- the name
istio-ingressgateway-service-account
couples the kubeflow deployment with istio gateway deployed from operator/istioctl, because istio gateway installed with Helm uses different SA (it should be also possible to use different gateway name and/or SA name if required) - it would allow OOB secure access from more gateways/istio LBs to access the service without any additional configuration
- if some platform uses yet another LB (like ALB in AWS; istio still have to be deployed in-cluster), it's also possible to define a rule where the traffic goes directly to the endpoint (here jupyter-web-app) and omit the istio-ingressgateway
- I don't see any security risks in dropping this requirement of access only through the istio-ingressgateway because the traffic must be authorized first to access either way
This is only for the reason of flexibility and ease of adoption.
- from: | |
- source: | |
principals: | |
- cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account | |
requestPrincipals: # new! Require JWT | |
- '*' | |
- from: | |
- source: | |
requestPrincipals: | |
- '*' |
Thank you so much for the review comments @kromanow94! I'll take a look on them today/tomorrow |
@kromanow94 I've addressed the review comments, and only left the ones that propose the removal of the IngressGateway declaration in the AuthorizationPolicies. I would like to avoid making this change in this PR. Mainly because this is a bigger discussion, to untangle the Istio IngressGateway, from the Kubeflow components. There are other places that are affected by this, like the AuthorizationPolicies created by Profiles (for allowing traffic for Notebooks and/or ISVCs). So I'd prefer that we tackle that problem of its own, in a proposal that captures all the aspects rather than doing some changes here that are not fully spec-ed out for the overall effort. WDYT? |
Given oauth2-proxy the information in https://www.kubeflow.org/docs/components/pipelines/user-guides/core-functions/connect-api/#full-kubeflow-subfrom-inside-clustersub is is really misleading. |
1. The service-mesh must drop (401) a request if the JWT is invalid (`RequestAuthentication`) | ||
2. The service-mesh must drop (403) a request if the JWT is not present, and the application expects requests to have a user identity (`AuthorizationPolicy`) | ||
3. The backends are not responsible for validating the JWTs or their existence | ||
4. The service-mesh must expose user and groups to `kubeflow-userid` and `kubeflow-groups` headers, after validating JWTs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will it remove the bearer token header with the JWT before forwarding the request to the backend or will the backend recieve the userid header and the bearer token?
"The recommended way is to use requestPrincipals: [""], as the Istio docs suggest, to accept only requests that have a JWT. The recommended way is to use requestPrincipals: [""], as the Istio docs suggest, to accept only requests that have a ?valid? JWT." later on suggests that the JWT has to be forwarded as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No no the JWT will stay in the Authorization
header, and the mesh will add the headers as an extra
Ok, this makes very much sense. Let's do it like that. Also, I wasn't able to resolve the threads but I either left a comment or a thumbs up where I agree on the resolution.
So I understand you suggest to update this docs with information on how to use the SA Token? BTW, since we're moving around some stuff for authz, maybe you're interested in having a service that will manage programmatic login? This would be something that replaces the Full Kubeflow (from outside cluster) flow. We have this little component that works with a websocket, can redirect to the auth page, get the cookies or a token from login response and send back via websocket to the client. We can also have a call sometime next week so I can showcase how would that work. |
Yes :-) this session hack i snot what we should advertise. |
Signed-off-by: Kimonas Sotirchos <kimwnasptd@gmail.com>
Signed-off-by: Kimonas Sotirchos <kimwnasptd@gmail.com>
Signed-off-by: Kimonas Sotirchos <kimwnasptd@gmail.com>
a3c1ac4
to
a4ba96a
Compare
@kromanow94 @juliusvonkohout I've done a pass and integrated your comments. Let me know if there's anything else |
For me it is anyway a /lgtm for a long time (despite the "nits" :-D) We can always reiterate and reiterating is easier if it is merged first. In the end it is a proposal that can change. |
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: juliusvonkohout The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Continuing from the discussion in #2747
After the
oauth2-proxy
PRs are merged we have made some changes on how JWTs are used from within the cluster (RequestAuthentication
) and how headers are added from these tokens.This lead to some issues in KFP, for which to resolve we'll need to have an agreed upon story on how to be working in the future with JWTs.
After agreeing on the above, this can also enable us to push the effort for supporting groups since we'll have an agreed upon way of working with identity information.
/cc @juliusvonkohout @kromanow94 @thesuperzapper @axel7083
cc @rimolive @DnPlas