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

Added proposal for "acting-as". #16933

Closed
wants to merge 1 commit into from

Conversation

erictune
Copy link
Member

@erictune erictune commented Nov 6, 2015

This change is Reviewable

@k8s-github-robot k8s-github-robot added kind/design Categorizes issue or PR as related to design. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Nov 6, 2015
@erictune
Copy link
Member Author

erictune commented Nov 6, 2015

@erictune
Copy link
Member Author

erictune commented Nov 6, 2015

@nikhiljindal

@smarterclayton
Copy link
Contributor

Not a ton of time to comment today, but in general some form of scoped delegation on behalf of the user is good. It's even better if it's the intersection of a service account for the controller (scoped) and the user context (scoped). Or even further, a named scope that the delegation occurs in (permission is intersection of controller, user, and a scope the controller applies).

@erictune
Copy link
Member Author

erictune commented Nov 6, 2015

@smarterclayton I don't want to involve a human user in the intersection. It should be possible for a human user to create a replication controller, and then leave the company, thus no longer appear in ldap, and that replication controller should not stop working. That is too tight a coupling between a corporate database and a production system. We've tried that tight coupling, and bad things happen.

@erictune
Copy link
Member Author

erictune commented Nov 6, 2015

@smarterclayton @liggitt does openshift already do something in this area?

@smarterclayton
Copy link
Contributor

It should be possible for a human user to create a replication controller, and then leave the company, thus no longer appear in ldap, and that replication controller should not stop working.

Sorry, wasn't implying that. I was merely saying that the actor the RC is acting on behalf of should be the service account (which is a user), and it should be clear that the "on behalf of" and the RC's permissions should be able to be made safe.

@smarterclayton
Copy link
Contributor

I personally do not believe end users should be the "actors" in the system except for very transient things (things that should run to completion within the scope of a period of employment with 99.9% certainty)

@erictune
Copy link
Member Author

erictune commented Nov 6, 2015

Agreed.

@smarterclayton
Copy link
Contributor

We run all controllers (well, almost all) under their own service accounts
that are only granted a subset of roles. However, they still often end up
with the ability to create pods across all namespaces (at least some of
them).

We do use pod security policy to limit the impact of the creation for many

  • the service account in the namespace must have the appropriate
    permissions, so the controller is not any more privileged than the highest
    role a service account in the namespace has.

On Nov 6, 2015, at 3:30 PM, Eric Tune notifications@github.com wrote:

@smarterclayton https://github.com/smarterclayton @liggitt
https://github.com/liggitt does openshift already do something in this
area?


Reply to this email directly or view it on GitHub
#16933 (comment)
.

master This does require users to change their flags, but we can support the
old way for several release cycles.
- change apiserver to recognize an "Acting-As" header in requests, and to check whether the
originally authenticated user is able to act as that user.
Copy link
Member

Choose a reason for hiding this comment

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

do you envision only being able to act as a user, or also as a group?
how do you envision the authn layer checking if a user (or group) is allowed to act as another user?

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 envisioned only being able to act as a user. I envision that the steps are:

  1. authenticate user as we do today
  2. authorize user to act-as another user
  3. lookup group membership of (effective) user
  4. authorize REST action using effective user and its group membership

I was thinking that we would only let you act-as a kubernetes ServiceAccount, not as another type of account. Since ServiceAccount is a kubernetes object, it can be referenced in Openshift (or other) Policy statements. So, you can have a Policy and Role like this:

kind: Role
...
rules:
  - resourceNames: [ "namespace/foo/serviceAccounts/default", ...]
  - verb: ["actAs"]
-----
kind: roleBinding
...
usernames: ["system:replicationController"]
roleRef: "that one up there"

which says that user "system:replicationController" can "actAs" (or maybe "use") the default service account for namespace foo (and probably every other namespace, as they get added.)

@liggitt
Copy link
Member

liggitt commented Nov 8, 2015

cc @deads2k

1. this is a common class of bugs in systems such as this.
1. we might trust ourselves to keep controllers in the main repo free from these bugs;
but we will not have time to closely review contributed code for these bugs.
1. out authorization rules will get more complex over time, so deputies will have
Copy link
Contributor

Choose a reason for hiding this comment

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

typo "out" should be "our"

@deads2k
Copy link
Contributor

deads2k commented Nov 10, 2015

Pulling @liggitt's comment out into the main thread:

It could help with the confused deputy, but it depends when it gets confused... if the problem is that it gets tricked into doing something cross-namespace, it could correctly lower its permissions to scope to the namespace it was tricked into, but it would be too late...
Do you envision changing controllers to operate on a single namespace at a time? That seems more likely to help, but also have a much larger performance impact (N list operations instead of a single one across all namespaces, etc)

I share the concern. I definitely want the ability for a user to act as a ServiceAccount, but I'm not certain that this approach reduces the trust required for controllers. Whoever enables the controller must still trust that the controller switches identity correctly. Meaning that the controller is triggered to request the correct SA and that code for selecting an SA is not bugged. That seems like I'm still trusting the controller to properly use all the permissions it has for its own identity and all the transitive permissions it gets from the SAs its allowed to act-as.

I still want the feature to allow a regular user to act as a more privileged service account for some tasks (sort of like sudo), but I'm not sure this helps with the controller trust problem.

@lavalamp
Copy link
Member

Is there a rule we can enforce to make controllers extremely unlikely to
have such bugs? Like, every object/request must have a "acting-as"
field/header, and the controller's own identity is not allowed to actually
perform mutations, only to list the appropriate things? I think that would
prevent the controller from accidentally using its own identity.

But I also think that at some level you have to trust that the system
components handle identity correctly.

On Tue, Nov 10, 2015 at 5:34 AM, David Eads notifications@github.com
wrote:

Pulling @liggitt https://github.com/liggitt's comment out into the main
thread:

It could help with the confused deputy, but it depends when it gets
confused... if the problem is that it gets tricked into doing something
cross-namespace, it could correctly lower its permissions to scope to the
namespace it was tricked into, but it would be too late...
Do you envision changing controllers to operate on a single namespace at a
time? That seems more likely to help, but also have a much larger
performance impact (N list operations instead of a single one across all
namespaces, etc)

I share the concern. I definitely want the ability for a user to act as a
ServiceAccount, but I'm not certain that this approach reduces the trust
required for controllers. Whoever enables the controller must still trust
that the controller switches identity correctly. Meaning that the
controller is triggered to request the correct SA and that code for
selecting an SA is not bugged. That seems like I'm still trusting the
controller to properly use all the permissions it has for its own identity
and all the transitive permissions it gets from the SAs its allowed to
act-as.

I still want the feature to allow a regular user to act as a more
privileged service account for some tasks (sort of like sudo), but I'm
not sure this helps with the controller trust problem.


Reply to this email directly or view it on GitHub
#16933 (comment)
.

@erictune
Copy link
Member Author

@yuvipanda

@erictune erictune force-pushed the auth-design-updates branch from 4d01f80 to 87e94a9 Compare May 17, 2016 18:12
@k8s-github-robot k8s-github-robot added retest-not-required-docs-only do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. labels Jul 22, 2016
@apelisse apelisse removed the do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. label Aug 11, 2016
@k8s-github-robot
Copy link

This PR hasn't been active in 90 days. Closing this PR. Please reopen if you would like to work towards merging this change, if/when the PR is ready for the next round of review.

cc @erictune

You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days

@k8s-bot
Copy link

k8s-bot commented Aug 15, 2016

GCE e2e build/test passed for commit 87e94a9.

@erictune erictune added release-note-none Denotes a PR that doesn't merit a release note. and removed release-note-label-needed labels Aug 23, 2016
@erictune
Copy link
Member Author

@deads2k You have implemented some of this, and some other things that this proposal did not forsee. Does it make sense to merge this and then update it, or abandon it, or something else?

@deads2k
Copy link
Contributor

deads2k commented Aug 24, 2016

@deads2k You have implemented some of this, and some other things that this proposal did not forsee. Does it make sense to merge this and then update it, or abandon it, or something else?

I've implemented the mechanics of impersonation (acting-as), but not the usage being described here.

I think we (at least @liggitt and myself) agree with you that we should stop using the insecure port for controllers and that we need to more tightly scope the powers that individual controllers have. We're less sure of using impersonation to do it.

Not much progress was made on stabilizing rbac in 1.4, but it is on my personal objective list for 1.5 so I'm hoping to make things like default policy achievable. I think that in combination with a special purpose "service accounts from namespace kube-infra are special" authorizer for alternative authorization approaches makes the "Special-purpose accounts" a viable option. How do you feel about pursuing that avenue?

@erictune
Copy link
Member Author

I like that approach for kubelet. I like it less for controller-manager
and scheduler. Here is why:

  • Kubelet has authorization requirements that are really hard to implement
    without making RBAC more complex, such as "kubelets should only be able to
    pull secrets for pods scheduled to them". Controllers and Scheduler don't
    have as difficult requirements, IMO.
  • We try to write controllers that are provided by the project in a way
    that third-parties can copy. Third parties cannot easily copy the customer
    authorizer pattern. Kubelet does not need to have third-party
    implementations, so no special requirement here.
  • There are so many kubelets that authorization efficiency (cycles spent in
    authz code in apiserver) is a concern. I don't know that this is a concern
    to the same degree for controllers.

On Wed, Aug 24, 2016 at 4:58 AM, David Eads notifications@github.com
wrote:

@deads2k https://github.com/deads2k You have implemented some of this,
and some other things that this proposal did not forsee. Does it make sense
to merge this and then update it, or abandon it, or something else?

I've implemented the mechanics of impersonation (acting-as), but not the
usage being described here.

I think we (at least @liggitt https://github.com/liggitt and myself)
agree with you that we should stop using the insecure port for controllers
and that we need to more tightly scope the powers that individual
controllers have. We're less sure of using impersonation to do it.

Not much progress was made on stabilizing rbac in 1.4, but it is on my
personal objective list for 1.5 so I'm hoping to make things like default
policy achievable. I think that in combination with a special purpose
"service accounts from namespace kube-infra are special" authorizer for
alternative authorization approaches makes the "Special-purpose accounts" a
viable option. How do you feel about pursuing that avenue?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#16933 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHuudl07O9gnoJJRD49G75_Hb7BiJh3pks5qjDHxgaJpZM4Gdp-q
.

@erictune
Copy link
Member Author

Impersonation can reduce instances of the confused deputy problem due to
bugs in controller implementations.

How do you and liggitt rate the importance of "avoid confused deputy"? Do
you know ways to address it other than impersonation?

On Mon, Aug 29, 2016 at 2:08 PM, Eric Tune etune@google.com wrote:

I like that approach for kubelet. I like it less for controller-manager
and scheduler. Here is why:

  • Kubelet has authorization requirements that are really hard to implement
    without making RBAC more complex, such as "kubelets should only be able to
    pull secrets for pods scheduled to them". Controllers and Scheduler don't
    have as difficult requirements, IMO.
  • We try to write controllers that are provided by the project in a way
    that third-parties can copy. Third parties cannot easily copy the customer
    authorizer pattern. Kubelet does not need to have third-party
    implementations, so no special requirement here.
  • There are so many kubelets that authorization efficiency (cycles spent
    in authz code in apiserver) is a concern. I don't know that this is a
    concern to the same degree for controllers.

On Wed, Aug 24, 2016 at 4:58 AM, David Eads notifications@github.com
wrote:

@deads2k https://github.com/deads2k You have implemented some of this,
and some other things that this proposal did not forsee. Does it make sense
to merge this and then update it, or abandon it, or something else?

I've implemented the mechanics of impersonation (acting-as), but not the
usage being described here.

I think we (at least @liggitt https://github.com/liggitt and myself)
agree with you that we should stop using the insecure port for controllers
and that we need to more tightly scope the powers that individual
controllers have. We're less sure of using impersonation to do it.

Not much progress was made on stabilizing rbac in 1.4, but it is on my
personal objective list for 1.5 so I'm hoping to make things like default
policy achievable. I think that in combination with a special purpose
"service accounts from namespace kube-infra are special" authorizer for
alternative authorization approaches makes the "Special-purpose accounts" a
viable option. How do you feel about pursuing that avenue?


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#16933 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHuudl07O9gnoJJRD49G75_Hb7BiJh3pks5qjDHxgaJpZM4Gdp-q
.

@k8s-bot
Copy link

k8s-bot commented Aug 30, 2016

Can one of the admins verify that this patch is reasonable to test? If so, please reply "ok to test".
(Note: "add to whitelist" is no longer supported. Please update configurations in kubernetes/test-infra/jenkins/job-configs/kubernetes-jenkins-pull instead.)

This message will repeat several times in short succession due to jenkinsci/ghprb-plugin#292. Sorry.

@deads2k
Copy link
Contributor

deads2k commented Aug 30, 2016

We try to write controllers that are provided by the project in a way
that third-parties can copy. Third parties cannot easily copy the customer
authorizer pattern.

A third party controller could provide a ClusterRole (or Role, if the controller is going to be "personal" in an namespace), which is then bound to a service account.

@deads2k
Copy link
Contributor

deads2k commented Aug 30, 2016

How do you and liggitt rate the importance of "avoid confused deputy"?

Important, but well bounded. In OpenShift, we bind individual controllers to roles which limit the controllers to the individual resources they must have access to run. For instance, the RS controller can

"get", "list", "watch", "update"    "replicasets"
"update"     "replicasets/status"
"list", "watch", "create", "delete"    "pods"
"create", "update", "patch"    "events"

That significantly reduces risk, since anyone able to create a replicaset has implicit control over pods already. That means that the confused deputy risk for the controller is only cross namespace attacks. Cross namespace bugs are actually pretty easy to review for since there's only one namespace involved per-action.

That why we aren't overly concerned about impersonation. The difficulty in code review for determining safe usage of two clients instead of one client and when to use which client (users probably shouldn't be creating events as a for instance) seems additive to the problem of cross namespace bug inspection.

With RBAC, its now possible to start using a similar strategy in kube. I'm working towards creating default ClusterRoles which can include the roles required for the individual controllers to run. Then there's more wiring to complete in order to get the SA tokens into the controllers, but I think its all achievable.

@deads2k
Copy link
Contributor

deads2k commented Sep 2, 2016

@erictune convinced me that we need a way to scope impersonation and one way of doing it is to intersect the rights of the impersonater with the rights of the impersonatee. In OpenShift, we do this using scopes inside of the user.Info.Extra field, but alternate approaches could make sense too.

We both agreed that the next step for controllers is to find a way to scope the overall powers of individual controllers (probably using ClusterRoles) and that this would be in addition to that effort, not instead of it.

@erictune as I understood the next steps, you were going to propose a mechanism for driving this intersection and demonstrate inside of a controller. We might end up taking the intersection first (it provides utility for callers regardless of whether controllers use it).

@k8s-github-robot k8s-github-robot added kind/design Categorizes issue or PR as related to design. kind/old-docs labels Dec 1, 2016
@k8s-github-robot
Copy link

Adding label:do-not-merge because PR changes docs prohibited to auto merge
See http://kubernetes.io/editdocs/ for information about editing docs

@k8s-github-robot k8s-github-robot added the do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. label Dec 1, 2016
@k8s-github-robot
Copy link

This PR hasn't been active in 90 days. Closing this PR. Please reopen if you would like to work towards merging this change, if/when the PR is ready for the next round of review.

cc @erictune

You can add 'keep-open' label to prevent this from happening again, or add a comment to keep it open another 90 days

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
do-not-merge DEPRECATED. Indicates that a PR should not merge. Label can only be manually applied/removed. kind/design Categorizes issue or PR as related to design. release-note-none Denotes a PR that doesn't merit a release note. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.