-
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
Getting Istio RBAC issues when submitting a pipeline from a Notebook #2747
Comments
@juliusvonkohout @kromanow94 after playing a bit around and catching up with the manifests/common/oidc-client/oauth2-proxy/components/istio-m2m/requestauthentication.yaml Lines 13 to 14 in 96ce068
Specifically, this But by adding this header it means that the request will not match the current AuthorizationPolicy, that blocks requests that do NOT come from the IngressGateway to set the manifests/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml Line 37 in 96ce068
|
In this case by removing the above lines, from the This comes back a bit to the discussion about using headers vs tokens everywhere. But to move us a bit forward I suggest that for the K8s issuer |
I haven't been following the oauth2-proxy stuff, but this is important because this issue will not just affect Notebook Pods. Users have always assumed that Pods that directly access the That is, there will be no JWT (from dex/oauth2-proxy) for these requests, because they authenticate themselves with their Pod service account token. See the "Full Kubeflow (from inside cluster)" part of this page for examples which need to work: |
I've put quite a bit of more thought after seeing the above. I'm preparing a small spec to go over the details. We'll need to indeed be careful on both the expectations around JWTs and also what changes to do, by having a uniform plan |
So what I propose for unblocking this is to
And for the above to ensure
If the header is not set, via |
@thesuperzapper yes, it is a critical feature that we have to fix for 1.9 I really like the JWT specification proposal and we should also create an additional test for that usecase to our github actions. |
Hey All, I'm finally back from vacation and can chime in. @kimwnasptd, to comment on the #2747 (comment):
I wouldn't call this the root cause. By removing the configuration from But, I'd call the root cause what you've described about the We also should take into account if we want to force auth check with oauth2-proxy directly for
I'm a fan of the first option because it is more secure, streamlined and promotes decoupling. I present you this diff that you can apply locally on your diff --git a/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml b/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml
index a9a45e5e..cbef023f 100644
--- a/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml
+++ b/apps/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml
@@ -32,10 +32,24 @@ spec:
- cluster.local/ns/kubeflow/sa/ml-pipeline-scheduledworkflow
- cluster.local/ns/kubeflow/sa/ml-pipeline-viewer-crd-service-account
- cluster.local/ns/kubeflow/sa/kubeflow-pipelines-cache
- # For user workloads, which cannot user http headers for authentication
- - when:
- - key: request.headers[kubeflow-userid]
- notValues: ['*']
+ - from:
+ - source:
+ requestPrincipals: ["*"]
+---
+apiVersion: security.istio.io/v1
+kind: AuthorizationPolicy
+metadata:
+ name: ml-pipeline-oauth2-proxy
+ namespace: kubeflow
+spec:
+ action: CUSTOM
+ provider:
+ name: oauth2-proxy
+ selector:
+ matchLabels:
+ app: ml-pipeline
+ rules:
+ - {}
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
diff --git a/common/oidc-client/oauth2-proxy/overlays/m2m-self-signed/kustomization.yaml b/common/oidc-client/oauth2-proxy/overlays/m2m-self-signed/kustomization.yaml
index fd56fa31..8e88dff7 100644
--- a/common/oidc-client/oauth2-proxy/overlays/m2m-self-signed/kustomization.yaml
+++ b/common/oidc-client/oauth2-proxy/overlays/m2m-self-signed/kustomization.yaml
@@ -16,4 +16,4 @@ configMapGenerator:
literals:
- ALLOW_SELF_SIGNED_ISSUER=true
- ENABLE_M2M_TOKENS=true
- - EXTRA_JWT_ISSUERS=https://kubernetes.default.svc.cluster.local=https://kubernetes.default.svc.cluster.local
+ - EXTRA_JWT_ISSUERS=https://kubernetes.default.svc.cluster.local=https://kubernetes.default.svc.cluster.local,https://kubernetes.default.svc.cluster.local=pipelines.kubeflow.org Now, assuming you also have the #!/usr/bin/env python3
from kfp import dsl
import kfp
client = kfp.Client()
experiment_name = "my-experiment"
experiment_namespace = "kubeflow-user-example-com"
@dsl.component
def add(a: float, b: float) -> float:
"""Calculates sum of two arguments"""
return a + b
@dsl.pipeline(
name="Addition pipeline",
description="An example pipeline that performs addition calculations.",
)
def add_pipeline(
a: float = 1.0,
b: float = 7.0,
):
first_add_task = add(a=a, b=4.0)
second_add_task = add(a=first_add_task.output, b=b)
try:
print("getting experiment...")
experiment = client.get_experiment(
experiment_name=experiment_name, namespace=experiment_namespace
)
print("got experiment!")
except Exception:
print("creating experiment...")
experiment = client.create_experiment(
name=experiment_name, namespace=experiment_namespace
)
print("created experiment!")
client.create_run_from_pipeline_func(
add_pipeline,
arguments={"a": 7.0, "b": 8.0},
experiment_id=experiment.experiment_id,
enable_caching=False,
) @kimwnasptd, I saw your proposal about unifying JWT handling. I like that you've already proposed usage of the I have a few thoughts and I'll put them there in incoming days, but in general, I'd suggest:
This way we have uniformed way of authz, both from out of cluster and in-cluster perspective, and we don't drop the security behind istio-ingressgateway. RBAC can still be defined with RoleBindings but the source of truth for auth should always be a JWT and never a header. So, from my perspective, I think it would be best to define a goal where at end we use only JWTs from Reference on the implementation of direct JWT verification: https://medium.com/@cheickzida/golang-implementing-jwt-token-authentication-bba9bfd84d60 |
Hey, I continued and updated some thoughts in the proposal: Uniform way for handling JWTs: #2748 (comment) In summary, I had some thoughts and decided to drop the emphasis on not removing and tightening the implementation of JWT in Kubeflow components. While this is still something I'd love to see, I understand that have to balance between the functionality and development and offload whatever possible to external components, so just relying on Istio to verify and authorize requests based on the JWTs is fine. With the above in mind, I agree that it should be enough to change the |
The ServiceAccount Token is a K8s Issued JWT and dex also provides JWT after login. Also, Please see:
From the surrounding architecture perspective, we're fully capable of using JWTs directly in KF Components. But, |
I put my comments in the proposal: Uniform way for handling JWTs. I like where this is going but we also have to cover for current release. I've made a PR where I change the authorize requests to ml-pipeline endpoint if contains any trusted principals (#2753) |
@kromanow94 we also need a negative test to check that it does not work without the proper token, but just the faked userid header. since we have to get RC.2 ready and Kimonas approved it in #2747 (comment). I merged your PR #2753, but we have to do a full assessment next week with more security tests. And we have to bring some of those changes to Kubeflow/pipelines or it will break with the next synchronization again. |
@juliusvonkohout didn't you mean @kromanow94 ? 😅 Yes, negative test also makes sense. I can take care of this but only next week. If you'd like my help on bringing those changes to |
Yes the right Romanov :-D Especially the change of the KFP authorizationpolicy to requestprincipals in their multi-user manifests is important. |
@nagar-ajay it works in https://github.com/kubeflow/manifests/actions/runs/9741004851/job/26879289585?pr=2781 and is in 1.9rc.2, but we will leave this issue open until it is fixed upstream. |
It is fixed in manifests and upstreaming is tracked in #2804 |
Validation Checklist
Version
1.9
Describe your issue
I tried to create a pipeline from the KFP SDK, from a Notebook, but the python code that creates the experiment/run is failing with the following errors
From the notebook cell
And from the logs of the KFP API Server istio sidecar
Steps to reproduce the issue
v1.9-branch
ipynb
with Data Passing pipeline https://github.com/kubeflow/pipelines/blob/master/samples/tutorials/Data%20passing%20in%20python%20components/Data%20passing%20in%20python%20components%20-%20Files.pyPut here any screenshots or videos (optional)
No response
The text was updated successfully, but these errors were encountered: