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

[tracking] Security, auth and logging in #964

Closed
Tracked by #2353
bryk opened this issue Jun 27, 2016 · 55 comments
Closed
Tracked by #2353

[tracking] Security, auth and logging in #964

bryk opened this issue Jun 27, 2016 · 55 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature.

Comments

@bryk
Copy link
Contributor

bryk commented Jun 27, 2016

Goals: Make the UI work with IAM (identity and access management). The UI should fail soft on things that user cannot see and/or cannot edit. Also, provide a login screen and make the UI work on behalf of a user.
Bonus goals: Integrate with IAM provider to proactively disable views/actions/buttons that user cannot see/modify.

Work estimate: 2 engs + UX desing for a quater

@maciaszczykm
Copy link
Member

Me and @floreks are willing to work on it, should be interesting :)

@bryk
Copy link
Contributor Author

bryk commented Jul 7, 2016

How are we moving forward with this? Should we talk on Monday?

@maciaszczykm
Copy link
Member

Okay, so after some delay I think it's time to take a closer look on this topic. I'd like to start discussion about it, so we can move forward after we establish some proposal. I've read documentation from https://github.com/kubernetes/kubernetes/blob/release-1.2/docs/design/access.md, but still it's not so clear what is the best way to implement following features for the dashboard:

  • login screen
  • making UI to act on behalf of a user (access control etc.)
  • access control management (modifying access rights etc. - only for certain users, i.e. admins)

I'll continue investigation and post some proposals. Please post your own ideas too.

@romlein I'd like to ask you for help with designing login screen when we'll finish discussion there.

CC @floreks @bryk @erictune @cheld

@erictune
Copy link
Member

@bryk are you looking for a single solution which will work on both GKE and OSS, or is it okay if the solution we decide on here is only for OSS?

@erictune
Copy link
Member

Login Screen (authentication)

If we can somehow get the user's Kubernetes cluster token (that kubectl uses and is in the .kube/config) into the browser, via cut-and-paste or some kind of oauth flow, then the browser could send that the Dashboard, and the dashboard could send the token to the about-to-be-added tokenreviews endpoint on the master. (kubernetes/kubernetes#28788) The master will translate this token to an authenticated username, or else say it is nobody.

Acting on behalf of user

Dashboard has its own credentials that it presents to the apiserver, e.g. as user "serviceaccount:kube-system:dashboard", when talking to the API server, but it sets the "Impersonate-User: alice" header in all its requests, which causes the API server to authorize the request as "alice".

Note that the Dashboard needs to List objects every time a user visits the page, as that user, or if it caches or watches stuff, it needs to have per-user caches or watches. It also needs to act as the user each time the user mutates something.

Access Control Management

I think editing ACLs might be out of scope for dashboard. On GKE, users will do this via the IAM tab of console.cloud.google.com. If they are using another hosted system, it will happen somewhere else. If they are running on OpenStack, then they might need to modify permissions via Keystone. If they are using Kubernetes RBAC (which is optional), then they need to use the CLI. At the moment, none of the Authz options provides a way to put ACLs on specific objects anyways, so it is not yet a common operation.

@erictune
Copy link
Member

Happy to set up a call to do a deeper dive on this. You can find my email on my github profile.

@danielromlein
Copy link
Contributor

Sounds good @maciaszczykm! Keep me posted. I'm happy to jump into designing the login screen.

@bryk
Copy link
Contributor Author

bryk commented Jul 21, 2016

@bryk are you looking for a single solution which will work on both GKE and OSS, or is it okay if the solution we decide on here is only for OSS?

This should work on both. I assume that on GKE the login part will be skipped or automatically connected to your Google account. But once you're logged in, everything stays the same, no matter whether you're on GKE or bare metal cluster.

@erictune
Copy link
Member

The tokenreview may not work on GKE. I sent you a doc about that. We may need a different login path. I'm not sure what that will be.

@mlbiam
Copy link
Contributor

mlbiam commented Aug 17, 2016

With 1.3 I have SSO into the dashboard working great with a reverse proxy and OIDC/OAuth2. I wouldn't create an explicit login screen, piggy back off of the RBAC model and the Auth model that is already supported. It would be great to have something that says who the logged in user is though.

@erictune
Copy link
Member

Marc, can you elaborate on your setup?

On Wed, Aug 17, 2016 at 9:48 AM, Marc Boorshtein notifications@github.com
wrote:

With 1.3 I have SSO into the dashboard working great with a reverse proxy
and OIDC/OAuth2. I wouldn't create an explicit login screen, piggy back off
of the RBAC model and the Auth model that is already supported. It would be
great to have something that says who the logged in user is though.


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

@mlbiam
Copy link
Contributor

mlbiam commented Aug 17, 2016

@erictune sure. Here's the diagram:
oidc_login

Actors:

  1. OpenUnison/ScaleJS - Hosts the user's main point of entry (and other identity services for RBAC) and reverse proxy in front of the API server
  2. KeyCloak - OpenID Connect Identity Provider
  3. API Server
  4. User

The flow:

  1. From a browser, the user accesses ScaleJS on OpenUnison
  2. User is redirected to KeyCloak to authenticate
  3. KeyCloak sends the user back to OpenUnison with an access token; OpenUnison presents users with link for the dashboard based on their permissions
  4. user clicks on the link, is sent to the /api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/ URL on the reverse proxy and for every request to the api server, OpenUnison creates a header for "Authorization: bearer ..."
  5. The API server takes the bearer token and verifies it against KC, getting the user's JWT

If the user wants to use kubectl instead then (#6) the user clicks on the OAuth2 Token link to get their current token and (#7) the user uses it with kubectl.

Here's a quick video of the whole thing in action: https://vimeo.com/179220012

@bryk
Copy link
Contributor Author

bryk commented Aug 19, 2016

@mlbiam Is this something generic that you can contribute to the project? I'd love to run something like open unision as a sidecar container and have all this that you explained here. This would be a first step before we can get user's details as you described in kubernetes/kubernetes#30784

@mlbiam
Copy link
Contributor

mlbiam commented Aug 19, 2016 via email

@bryk
Copy link
Contributor Author

bryk commented Aug 19, 2016

I need to clarify things in my head. Can I run OpenUnison as a sidecar container in Dashboard UI pod, then expose OpenUnison to the internet and reverse-proxy to Dashboard UI running on localhost?

@mlbiam
Copy link
Contributor

mlbiam commented Aug 19, 2016

@bryk

The short version is "yes" - Correct me if I'm wrong, but what I think you are looking for is just the SSO with the dashboard and the ability to get your token from the web browser? If so I can prototype a container that would take a number of environment variables pretty quickly. Then it would just be a matter of creating a java keystore and mounting it as a secret in k8s and adding the container as a sidecar to the dashboard pod (with the secret and environment variables).

The details:

OpenUnison is a war file that can be deployed into any java servlet container, including one in a docker container. My thought was to:

  1. Create a quick start like https://github.com/TremoloSecurity/openunison-qs-s2i that would have environment variables for the host, the OIDC idp information, the api server, etc.
  2. Create a java keystore that contains the certs for the api server and odic idp and mount it as a secret to /etc/openunison in the pod
  3. Use our source2image container on dockerhub (https://hub.docker.com/r/tremolosecurity/openunisons2idocker/) and deploy the image into an accessible repo (like dockerhub)
  4. Reference the new image in your pod definition including the values for the environment variables defined in your unison.xml and myvd.conf

I suppose if all you wanted was the scalejs dashboard for the oauth2 token viewer and sso integration with the dashboard, but no user provisioning or access request management, we could create a standard image and you could skip 1 & 3 and it would just be create the keystore and the pod definition. For just SSO we wouldn't need directory access, we would just rely on the OIDC idp. The issue at that point would be that you still need a database for the ScaleJS pieces, but we can add a feature that would allow it to run sso only functions without a db (ie seeing the links get generated).

OK, so after rambling through this I see two different scenarios:

SSO + Token Only

OpenUnison is configured as an OIDC client through environment variables. The ScaleJS Token app would be deployed so you could get your access token out of the oidc idp. There would be no dependency on a relational database or directory so the steps to deploy would be:

  1. create a keystore with the correct certificates and add it to a secret that is referenced in the pod
  2. Add the continer on dockerhub we will create as a sidecar
  3. add the correct environment variables to the pod

This will let users SSO into the dashboard and get their token. There would be no authorizations, that would be up to a combination of the dashboard and the oidc idp. Since ScaleJS Main (thats what generates the links for the oauth2 token and dashboard in the video) won't be there, we'd need to have a static html page in place for users to have something to click on, but thats easy.

Kubernetes Identity Manager

Where we started with this idea was to create an identity manager for Kubernetes. Something that would let you define workflows and approvers for access to k8s via the RBAC model. That would need to be more dynamic since the workflows are in the unison.xml file. Thats a larger scope though then I think what you're asking for.

@hjacobs
Copy link

hjacobs commented Jan 6, 2017

We at Zalando would also love to see the "dashboard impersonates user" feature 😄

In our case it would simply need to pass through an OAuth Bearer token to the API server (we use an OAuth proxy in front of the Kubernetes dashboard which would inject the user's OAuth Bearer access token).

@bryk
Copy link
Contributor Author

bryk commented Jan 18, 2017

@hjacobs There's a PR for this already: #1539

@maciaszczykm
Copy link
Member

Issue list:

  • Dashboard shouldn't be super-user,
  • Implement full authorization or just fully-functional token forwarding?
  • What about cookies and login page?

@maciaszczykm maciaszczykm added this to the 2017 roadmap milestone Apr 7, 2017
@kfox1111
Copy link

kfox1111 commented Apr 7, 2017

my $0.02:

+1 to no super user dashboard.

token forwarding. full authentication is a large amount of work, duplicated from other places, and security code so risky. Helm and Grafana, and other services that act on behalf of the user also need some kind of authentication code if its not shared. Lets share it, benefiting everyone.

@maciaszczykm
Copy link
Member

@kfox1111 I saw the issue, where you mentioned, that we are talking about continuing to work on authentication. We would gladly accept any kind of help there :) Can you add anything to action points, that I have mentioned in above comment? Let's keep in touch to push this forward.

@zhouhaibing089
Copy link
Contributor

Login functionality is too diversity, user can supply token, username/password, certificates, etc, It is not easy to come up with a general solution with dashboard, but at least, we should be able to make it easy to register plugins. That would basically means we can design several pages and each of them could be implemented with different ways:

  1. password: https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go#L42: Basic auth: username combination with password;
  2. token: https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go#L28: Bearer token;
  3. request: https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/authentication/authenticator/interfaces.go#L35: Certificates;

Impersonation is a complementary part, The dashboard should only take the responsibility of authentication, and once it succeeds, it should leverage the impersonation to do the rest.

@maciaszczykm
Copy link
Member

Already done.

@nailgun
Copy link

nailgun commented Sep 28, 2017

Where can we get information about this? AFAIK, anyone who has access to dashboard in fact has "root" access to a cluster despite of RBAC settings.

@maciaszczykm
Copy link
Member

@nailgun Check 1.7.0 release and recently introduced wiki pages & landing page. The Dashboard uses a minimal set of privileges by default at the moment. To make it work with existing cluster you will probably need to remove old SA and create new resources as it is described in our guides.

@seh
Copy link

seh commented Sep 28, 2017

The Wiki doesn't mention granting the "impersonate" verb to the dashboard's service account via a ClusterRoleBinding. Is the dashboard using the user impersonation facility to restrict its capabilities when talking to the API server?

@liggitt
Copy link
Member

liggitt commented Sep 28, 2017

Is the dashboard using the user impersonation facility to restrict its capabilities when talking to the API server?

Definitely not. Granting the ability to impersonate arbitrary users is an expansion of power, not a restriction

@seh
Copy link

seh commented Sep 28, 2017

How, then, is the Dashboard using the credentials submitted by users through its login dialog to restrict what each user is allowed to do once logged in?

@floreks
Copy link
Member

floreks commented Sep 28, 2017

We are simply using given credentials to create kubernetes client structure. It is created on every request.

@seh
Copy link

seh commented Sep 28, 2017

Interesting. @liggitt, isn't that what you had advised us not to do for the Helm project?

@liggitt
Copy link
Member

liggitt commented Sep 28, 2017

@liggitt, isn't that what you had advised us not to do for the Helm project?

for x509 credentials, absolutely (echoed here)

for token/basic auth, the user should authenticate to systems other than the API server (like the dashboard) with a credential scoped to that particular audience (and possibly scoped in power). the best way to do that would be to have the dashboard initiate an oauth flow to obtain an API token for the user. However, not all clusters have an oauth server available or the ability to create scoped tokens, so the dashboard made the choice to just take the user's basic or bearer credential. If you consider the dashboard part of the same auth domain as the API server, that's somewhat tolerable. If you consider the dashboard to be no different than any other application running on top of the cluster (as I do), then we should still be pushing to enable the delegated/scoped token, rather than asking the user for their credentials. The dashboard adding an option to use an OAuth flow for clusters which have that available would go a long way.

@floreks
Copy link
Member

floreks commented Sep 28, 2017

The dashboard adding an option to use an OAuth flow for clusters which have that available would go a long way.

It's on our list. Still it's possible to configure an OAuth proxy that will take care of retrieving and passing token to Dashboard. We are also checking for token header presence.

@floreks floreks mentioned this issue Sep 28, 2017
8 tasks
@seh
Copy link

seh commented Sep 28, 2017

In this model, @LiGgit, would the token retrieved via OAuth and submitted to the dashboard (and, transitively, to the API server) authenticate as the user (and his groups, etc.), or as some other identity with permissions even more restrictive than the user's normal permissions within the cluster?

@seh
Copy link

seh commented Sep 28, 2017

I'm sorry that I missed #2206 while it was underway. I thought it was all still far in the future, and hadn't been paying close enough attention to this project.

@floreks
Copy link
Member

floreks commented Sep 28, 2017

This model is no different than using kubectl with token set in kubeconfig file. Token is passed to API server and all roles are applied that are related to "user" tied to this token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

No branches or pull requests