Dashboard: Dashboard authentication and authorization

Created on 12 Jul 2016  路  17Comments  路  Source: kubernetes/dashboard

Issue details

I have two dashboards, one is the admin-dashboard, deployed using the kube-system:default service account, that should be able to do all operations within any namespace. Then, I have another dashboard, the developer one, that should only be able to see the things in the kube-system namespace, but not delete or create. In other namespaces, it should be able to create and delete. This dashboard is deployed using another service account, kube-system:dashboard-dev that has readonly permissions in kube-system.

This two dashboards are running correctly and working as expected, but I also want to control what users can access to each of the dashboards (using, for now, basic auth). For testing purposes I have two users, admin, and developer. The authorization policy of admin is that he is allowed to get into everything, and the one of the developer is that he is only allowed to use the developer dashboard

The idea of this approach is to have two users, one admin and one developer. The admin can do whatever he wants using kubectl or using the admin dashboard. The developer should be able to do everything with kubectl only in the default namespace, and reading in the kube-system. The developer should also be able to access the developer dashboard.

Environment
  • Authorization-mode=ABAC
  • Using basic authentication: two users, admin and developer
Dashboard version: 1.1.0
Kubernetes version: 1.2.4
Operating system: CentOS 7
Steps to reproduce
  • Deploy a dashboard using an specific service account, i.e. dashboard-dev
    The authorization policy of that service account is:
    {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"system:serviceaccount:kube-system:dashboard-dev","namespace": "kube-system", "resource": "*", "apiGroup":"*", "nonResourcePath": "*", "readonly": true}}
    {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"system:serviceaccount:kube-system:dashboard-dev","namespace": "default", "resource": "*", "apiGroup":"*", "nonResourcePath": "*"}}
  • Access to the dashboard using a user with limited permissions, i.e. developer, with the following authorization policy:
    {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"developer","namespace": "kube-system", "resource": "*", "apiGroup":"*", "nonResourcePath": "*", "readonly":true}}
    {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user":"developer","namespace": "default", "resource": "*", "apiGroup":"*", "nonResourcePath": "*"}}

    Observed result
  • You can access to the dashboard login in the authentication prompt with the admin user. The dashboard works as expected. This is, it cannot delete or create anything inside kube-system, but it can do it in default namespace.

  • You cannot access to the dashboard using the developer user. The browser shows this plain text message: Forbidden: "/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard"

    Expected result
  • Developer user can access to the dashboard.

Any insight or explanation about why this is happening? or maybe if it is even possible to achieve this?

Thanks in advance!

Most helpful comment

In following months we plan to make Dashboard work on-behalf-of a user. I think this would fix the problem. You'd then start one dashboard instance and then when a user connects to it, only their permissions would be used.

All 17 comments

You cannot access to the dashboard using the developer user. The browser shows this plain text message: Forbidden: "/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard"

I think the problem is that non-admin users cannot use the proxy feature. @erictune am I correct?

Does it work if you use this url instead?
/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/

@erictune that works! thank you very much! Could you please give a brief explanation about why changing the place of the proxy solves this problem?

Just as an educated guess, is the kubernetes-dashboard API invoking the proxy using the service account and not directly using the authenticated user?

Anyway, thanks again, this will make things a bit easier.

EDIT: not everyhting works. I can access to the Developer dashboard with the developer user using the url that you provided, but when I try to create apps I get this:

dashboard

I don't know why it works better. It was just a hunch. But I'm pretty sure it doesn't have to do with service accounts. I think it may have to do with those two ways of specifying proxy being handled by completely different code, and they have different ways of setting the ReadOnly attribute (used internally, and passed to the ABAC code). I looked for a while but couldn't figure out where that happens. Maybe someone from @kubernetes/sig-api-machinery or @kubernetes/sig-auth knows.

As for the imagereference stuff, I don't know how dashboard decides who is authorized to do api/v1/appdeployment/validate/imagereference.

@bryk can hopefully explain last item.

Everything going through api/v1/proxy is assigned a proxy verb by the RequestInfoResolver. We eventually realized that made it harder to describe proxy behaviors on specific things, so for the service/name/proxy subresource, the verb matches the http verb (to lower), resource=service, subresource=proxy.

The abac policy treats a get there as read-only even though it's not necessarily read-only. rbac can control access to the subresource with fine granularity.

EDIT: not everyhting works. I can access to the Developer dashboard with the developer user using the url that you provided, but when I try to create apps I get this:

@kanor1306 Is this only this action in the UI that fails? Or something else too? Can you do POST request to the URL that fails? (E.g., via curl)

@bryk there are more things that fail:

  • api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/api/v1/appdeployment/validate/name -> This is invoked when you fill in the Name of the app that you want to deploy in the _Deploy a Containerized App_ popup.
  • /api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/api/v1/appdeploymentfromfile -> invoked when trying to create a pod via a YAML file.
  • api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/api/v1/pod/namespace/default/name/mailhog-vp9va -> Previously I created in default a mailhog app, and when trying to delete it from the dashboard with the developer user, I got this.

Just as extra information, all return 403: Forbidden. Also I have to say that I tried this having previously selected the default namespace, just to be sure that I was in the right place.

About doing this requests via curl, it didn't work for the developer user, but it did with the admin user. This was the results in the developer case:

$ curl -k -H "Content-Type: application/json" -X POST -d '{"reference":"mailhog/mailhog"}' https://developer:[email protected]/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/api/v1/appdeployment/validate/imagereference  

Forbidden: "/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/api/v1/appdeployment/validate/imagereference"%

With the rest of the URLs it happens the same, they work with admin but not with developer.

@deads2k is RBAC already available to be used? I thought that it was in development yet

Just as extra information, all return 403: Forbidden.

I think this has something to do with the proxy service. We do no additional checking at all. The difference in those URLs is that we do HTTP POST/DELETE there.
@erictune Should dev role here be able to do HTTP POST/DELETE to a proxy url?

Your examples seem to be trying to POST things as the developer user to the dashboard (which is in the kube-system namespace), but your policy only grants readonly access to that namespace.

@liggitt now that you mention it, makes sense that the developer is not allowed to do it, because it really is a POST to the kube-system, which is out of the developer permissions.

I guess that my approach to the problem is not the right one. I was expecting that the dashboard or kubernetes would notice that although the POST is done through a kube-system app, it is trying to modify the default namespace, not the kube-system. But I think that my understanding of the internals of the authentication/authorization in Kubernetes are a bit limited.

Thanks everybody for your insight

In following months we plan to make Dashboard work on-behalf-of a user. I think this would fix the problem. You'd then start one dashboard instance and then when a user connects to it, only their permissions would be used.

Ok @bryk, thanks for the help. I'll close the issue then.

@bryk Hi, that's a good idea that I share to solve the authx issues. For dashboard's backend to impersonate as credentials got from frontend to talk to api server, it will be clean, simple and easy solution for all the questions asked for the area. Currently the backend talks to api server stiffly and always by token embedded into its pod. Would you give an update on how is it going in this direction?

@bryk Any update on when user based credentials will be used instead of the built in service account? Or at least a tracking issue for it.

The key to date is to create separate dashboards per user running with different service accounts.
Then create RBAC policys for what the different SA's are allowed to do or what namespaces they are allowed to operate in.

Was this page helpful?
0 / 5 - 0 ratings