Skip to content
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

feat(backend): Refactor authz to perform SubjectAccessReview. Fixes #3513 #4723

Merged
merged 10 commits into from
Nov 17, 2020

Conversation

elikatsis
Copy link
Member

Description of your changes:

With this PR we implement the refactoring described in #3513.

In the past, KFP used KFAM for its authorization checks, checking only if the user can view the corresponding namespace.
We now refactor the authorization mechanism to perform proper and fine-grained authorization via K8s RBAC and SubjectAccessReview.

Closes #3513

/assign @Bobgy

cc @yanniszark

Checklist:

Copy link
Contributor

@Bobgy Bobgy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much @elikatsis for the contribution! I have been looking forward for this for a while!

Some early feedback first. I haven't gone through everything.

@Bobgy
Copy link
Contributor

Bobgy commented Nov 6, 2020

@elikatsis I've got one general question, what would be the replacement you think for KFAM for namespace discovery?
Previously, we relied on centraldashboard talking to KFAM to get that, but I believe we can no longer do so if we completely remove KFAM.

I'm thinking about listing all namespaces with a certain pipelines.kubeflow.org/xxx label and build a new selector using this info collected in backend. I wonder what do you think about it.

/cc @yanniszark

@elikatsis
Copy link
Member Author

/retest

@Bobgy
Copy link
Contributor

Bobgy commented Nov 11, 2020

I was kind of busy, will review tomorrow

Copy link
Contributor

@Bobgy Bobgy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you so much @elikatsis!
I just read through all the code, left some nit pickings. The high-level structure looks awesome to me. Let's follow up with some details and I think we'll be good to go.

Another general nit picking I've seen a few times is that for each resource we defined a canAccessXXX(id) method that takes the ID, so that we needs to first fetch this resource to know its namespace. In cases that we already fetch this resource and know its namespace, we wrote one-off boilerplate code to fetch the resource and check authorization.

I think we can simplify a little bit by defining two utility methods for each resource:

  • canAccessXxxById(id, verb) --- fetches the resource inside and figures out namespace/name
  • canAccessXxx(namespace, name, verb) --- we are already fetching the resource, so we can pass namespace and name directly

canAccessXxxById will be straightforward to implement using canAccessXxx and we can avoid quite some duplication there.

clusterRoleSelectors:
- matchLabels:
rbac.authorization.kubeflow.org/aggregate-to-kubeflow-pipeline-edit: "true"
rules: []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we separate out actual rules to aggregate-to-pipeline-view ClusterRole?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Bobgy,
Great question! The answer is this essentially: kubernetes/kubernetes#65171

TL;DR: We can't have both aggregation and rules in a [Cluster]Role. The rules will be ignored. This is why we need to define our rules in some [Cluster]Roles and then have one role to find them, one role to bring them, and in itself bind them 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation! Good to know. : )

backend/src/apiserver/server/auth_server_test.go Outdated Show resolved Hide resolved
backend/src/apiserver/server/experiment_server.go Outdated Show resolved Hide resolved
backend/src/apiserver/server/util.go Show resolved Hide resolved
backend/src/apiserver/server/job_server.go Outdated Show resolved Hide resolved
@Bobgy
Copy link
Contributor

Bobgy commented Nov 12, 2020

Other than that, can you resolve the conflicts?

@maganaluis
Copy link
Contributor

We are working on #4197 and I just realized our changes will also have conflicts with this PR. Just for my own planning, will this be merged for the release 1.3? What else will we need to integrate with SubjectAccessReview. I know the CentralDashboard also uses KFam.

@elikatsis @Bobgy

@Bobgy
Copy link
Contributor

Bobgy commented Nov 16, 2020

Yes, I think as long as @elikatsis gets through the comments, we can merge.

It should be ready with kubeflow 1.3

This change is compatible with central dashboard, profile controller and kfam, because profile controller should already give service accounts rolebindings that can aggregate ones in this PR.

@Bobgy
Copy link
Contributor

Bobgy commented Nov 16, 2020

It'll be ideal if we can get rid of kfam from central dashboard too, so that we can completely remove it from the manifests, but there are still some unanswered design questions.

@elikatsis elikatsis force-pushed the feature-subject-access-review branch 2 times, most recently from 29827e3 to a19543e Compare November 16, 2020 16:41
@elikatsis
Copy link
Member Author

@Bobgy
I rebased and force-pushed. The minor nits (gcp marketplace manifests and forgotten double error check) are included in the "old" commits.
For the comments about

  • centralized check for multi-user shared mode
  • use canAccessXXX() instead of isAuthorized()
  • enhancement on error assertion wrt unauthorized calls
    I have added two fixup commits. I will squash them if they look good to you.

As far as having general canAccessXXX() and canAccessXXXById() functions, I think we don't need them. This is covered by each server's methods (see first fixup! commit). Implementing them in a different place and have the server use them looks like it adds complexity instead of simplifying things.

In preparation of SubjectAccessReview, we implement some helpers to
create a new Kubernetes Authorization clientset and return the
SubjectAccessReview client.
We also define some fake clients to be used by future tests.
In preparation of SubjectAccessReview, introduce RBAC groups, resources,
and verbs.
@elikatsis elikatsis force-pushed the feature-subject-access-review branch 2 times, most recently from a3a7abd to 9323c40 Compare November 16, 2020 18:12
Authorization should be based on performing some action on a resource
living in a namespace. This commit refactors the authorization utilities
to reflect this and perform SubjectAccessReview.

This commit also deletes some tests based on old authn/authz mechanism.
A following commit will fix/extend the tests for the new mechanism
}

glog.Infof("Authorized user %s in namespace %s", userIdentity, namespace)
glog.Infof("Authorized user '%s': %+v", userIdentity, resourceAttributes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These authorization logs will be very common, every request comes with it.
Shall we change log level to trace or debug?

For most of the cases, users should depend on error message for debugging, rather than api server logs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only see Info, Warning, Error, and Fatal levels. Can you help me how can I do debug or sth different?
Here's what I found in the repo, not sure if it helps: https://github.com/golang/glog/blob/23def4e6c14b4da8ac2ed8007337bc5eb5007998/glog.go#L91-L115

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, sorry I thought there were more. Then let's go with info for now.

Copy link
Contributor

@Bobgy Bobgy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only got two comments left. Everything else looks great to me!
Thank you so much @elikatsis!

/lgtm

With KFAM authorization, we passed only the namespace attribute for
authorization. With SubjectAccessReview, we need a richer list of
attributes. Thus, we adjust endpoints to pass request details (resource
attributes) necessary for authorizing the request. We only change the
already authorized endpoints, not introducing any new checks.
Since we no longer use KFAM, we may as well purge it
Signed-off-by: Ilias Katsakioris <[email protected]>
* API Server: Allow creating SubjectAccessReviews
* Add view/edit roles in a multi-user kustomization
@elikatsis
Copy link
Member Author

@Bobgy I added the comment and squashed the fixups. If you can help me selecting the logging level, we'll be golden!

@Bobgy
Copy link
Contributor

Bobgy commented Nov 17, 2020

Do you need @yanniszark 's review?
Everything good on my side

@elikatsis
Copy link
Member Author

@Bobgy we have already reviewed this internally, so we should be good to go. Thank you very much for your comments! 😃

@Bobgy
Copy link
Contributor

Bobgy commented Nov 17, 2020

/lgtm
/approve
Cool, I am feeling excited about the huge potential this brings. Thank you again for this great contribution!

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Bobgy, elikatsis

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot merged commit 39203d5 into kubeflow:master Nov 17, 2020
elikatsis added a commit to arrikto/kubeflow-manifests that referenced this pull request Nov 18, 2020
* Update apiserver role to allow creating SubjectAccessReviews
* Add roles which get aggregated to kubeflow-view and kubeflow-edit

Original PR: kubeflow/pipelines#4723

Signed-off-by: Ilias Katsakioris <[email protected]>
@elikatsis elikatsis deleted the feature-subject-access-review branch November 23, 2020 12:20
Jeffwan pushed a commit to Jeffwan/pipelines that referenced this pull request Dec 9, 2020
…ubeflow#3513 (kubeflow#4723)

* [Backend] Return proper error codes for failures during auth

* [Backend] Implement helpers to initialize a SubjectAccessReview client

In preparation of SubjectAccessReview, we implement some helpers to
create a new Kubernetes Authorization clientset and return the
SubjectAccessReview client.
We also define some fake clients to be used by future tests.

* [Backend] Introduce RBAC-related constants

In preparation of SubjectAccessReview, introduce RBAC groups, resources,
and verbs.

* [Backend] Extend managers with a SubjectAccessReviewClient

* [Backend] Refactor the authorization mechanism for requests

Authorization should be based on performing some action on a resource
living in a namespace. This commit refactors the authorization utilities
to reflect this and perform SubjectAccessReview.

This commit also deletes some tests based on old authn/authz mechanism.
A following commit will fix/extend the tests for the new mechanism

* [Backend] Adjust endpoints to pass resource attributes for authz

With KFAM authorization, we passed only the namespace attribute for
authorization. With SubjectAccessReview, we need a richer list of
attributes. Thus, we adjust endpoints to pass request details (resource
attributes) necessary for authorizing the request. We only change the
already authorized endpoints, not introducing any new checks.

* [Backend] Adjust apiserver/server tests to SubjectAccessReview

* [Backend] Purge KFAM

Since we no longer use KFAM, we may as well purge it

* [Backend] Update BUILD files

Signed-off-by: Ilias Katsakioris <[email protected]>

* [Manifests] Extend manifests for SubjectAccessReview

* API Server: Allow creating SubjectAccessReviews
* Add view/edit roles in a multi-user kustomization
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Multi-User Authorization: Add support for K8s RBAC via SubjectAccessReview
5 participants