Git Product home page Git Product logo

kubelogin's Introduction

kubelogin go Go Report Card

This is a kubectl plugin for Kubernetes OpenID Connect (OIDC) authentication, also known as kubectl oidc-login.

Here is an example of Kubernetes authentication with the Google Identity Platform:

screencast

Kubelogin is designed to run as a client-go credential plugin. When you run kubectl, kubelogin opens the browser and you can log in to the provider. Then kubelogin gets a token from the provider and kubectl access Kubernetes APIs with the token. Take a look at the diagram:

Diagram of the credential plugin

Getting Started

Setup

Install the latest release from Homebrew, Krew, Chocolatey or GitHub Releases.

# Homebrew (macOS and Linux)
brew install int128/kubelogin/kubelogin

# Krew (macOS, Linux, Windows and ARM)
kubectl krew install oidc-login

# Chocolatey (Windows)
choco install kubelogin

If you install via GitHub releases, you need to put the kubelogin binary on your path under the name kubectl-oidc_login so that the kubectl plugin mechanism can find it when you invoke kubectl oidc-login. The other install methods do this for you.

You need to set up the OIDC provider, cluster role binding, Kubernetes API server and kubeconfig. The kubeconfig looks like:

users:
- name: oidc
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubectl
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=ISSUER_URL
      - --oidc-client-id=YOUR_CLIENT_ID
      - --oidc-client-secret=YOUR_CLIENT_SECRET

See setup guide for more.

Run

Run kubectl.

kubectl get pods

Kubectl executes kubelogin before calling the Kubernetes APIs. Kubelogin automatically opens the browser, and you can log in to the provider.

keycloak-login

After authentication, kubelogin returns the credentials to kubectl and kubectl then calls the Kubernetes APIs with these credentials.

% kubectl get pods
Open http://localhost:8000 for authentication
NAME                          READY   STATUS    RESTARTS   AGE
echoserver-86c78fdccd-nzmd5   1/1     Running   0          26d

Kubelogin writes the ID token and refresh token to the token cache file.

If the cached ID token is valid, kubelogin just returns it. If the cached ID token has expired, kubelogin will refresh the token using the refresh token. If the refresh token has expired, kubelogin will perform re-authentication (you will have to login via browser again).

Troubleshoot

You can log out by removing the token cache directory (default ~/.kube/cache/oidc-login). Kubelogin will ask you to login via browser again if the token cache file does not exist i.e., it starts with a clean slate

You can dump claims of an ID token by setup command.

% kubectl oidc-login setup --oidc-issuer-url https://accounts.google.com --oidc-client-id REDACTED --oidc-client-secret REDACTED
...
You got a token with the following claims:

{
  "sub": "********",
  "iss": "https://accounts.google.com",
  "aud": "********",
  ...
}

You can increase the log level by -v1 option.

users:
- name: oidc
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubectl
      args:
      - oidc-login
      - get-token
      - -v1

You can verify kubelogin works with your provider using acceptance test.

Docs

Contributions

This is an open source software licensed under Apache License 2.0. Feel free to open issues and pull requests for improving code and documents.

This software is developed with GoLand licensed for open source development. Special thanks for the support.

kubelogin's People

Contributors

bastianccm avatar baykonur avatar creydr avatar dependabot-preview[bot] avatar dependabot[bot] avatar eric-poitras avatar gaima8 avatar int128 avatar irons avatar lindhe avatar linki avatar mattias- avatar mayurwaghmode avatar mkmik avatar mmb avatar mozgiii avatar mozillazg avatar opqdonut avatar pedrokiefer avatar peterholko-pingidentity avatar renovate-bot avatar renovate[bot] avatar rnikoopour avatar stang avatar teejaded avatar thomasalxdmy avatar towo avatar vadasambar avatar willchertoff avatar xenithorb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kubelogin's Issues

Not able to login as different user or logout until token expires

Kind: feature request

Description: When logged with OIDC based user, there are no direct (user friendly) options to logout or login with another credentials. User has to wait until token expires or needs to open Keycloak console page to logout.

Also for some time I was able to login with different user, but that stopped working with no obvious changes on both Kubernetes and client sides. After running kubelogin, browser automatically opens new tab and closes it. Kubelogin gets some (cached??) token value and kubectl remains happy with old credentials. If I run kubelogin with "/skip-open-browser" and open "http://localhost:8000" myself, I immediately get "OK" response, instead of login prompt.

If I clear browsing history, then login prompt is presented as expected.

OS: Windows 10, build: 1607
Browser: Chrome, Version 71.0.3578.98
Kubelogin: 1.8

Can browse be fed with some "no cache" options? Or was this behavior intentional?

Scopes option

Currently kubelogin sends an authentication request with the openid email scopes. It is better that a user can specify the scopes by some option.

Originally #5 (comment) by @azurewraith.

client-go credentials plugin error

The client-go plugin functionality returns an error whenever refreshing the token and cause the command to not execute. The new token is still acquired.

> kubectl get pods
Open http://localhost:18000 for authentication
[30191:30216:0729/154608.580065:ERROR:browser_process_sub_thread.cc(221)] Waited 3 ms for network service
You got a valid token until 2019-07-29 15:47:08 -0400 EDT
Unable to connect to the server: getting credentials: decoding stdout: couldn't get version/kind; json parse error: json: cannot unmarshal string into Go value of type struct { APIVersion string "json:\"apiVersion,omitempty\""; Kind string "json:\"kind,omitempty\"" }

kubeconfig

users:
- name: grunt
  user:
    exec:
      apiVersion: "client.authentication.k8s.io/v1beta1"
      command: kubectl
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://<URL>/auth/realms/master
      - --oidc-client-id=kubernetes
      - --oidc-client-secret=<SECRET>
      - --certificate-authority=./kube-ca.pem

Feature suggestion: Daemon mode + multi kluster

I pretty much run klogin in a for loop all the time, because we have short access key life times (30 minutes) and I don't want to see 'you must login again' messages all the time

A daemon mode that does this automatically would be super cool. e.g. klogin -d -period=20m (daemon mode, refresh every 20 minutes)

For super bonus points if it could be logging me into a few clusters at the same time (-c "kluster1,kluster2,kluster3") that'd be awesome, so that i don't have to klogin again when i switch

Refresh token is empty string

I have something similar to this issue, the IdP we are using is AD FS 4.0 on Windows Server 2016.

We get the token id but the refresh token is literally "".

We start the kube-apiserver with the following extra arguments:

apiServer:
  extraArgs:
    oidc-client-id: "<CLIENT ID>"
    oidc-issuer-url: "https://IDP ENDPOINT"
    oidc-username-claim: "upn"
    oidc-username-prefix: "-"

Manual mode : no accces to http://localhost:8000

Hello everyone,

I have a kubernetes cluster on premise install on virtual machine linux Centos.

I want to use kubelogin to connect via our own OIDC provider.

I configure the apiserver to authorise oidc connexion.
I configure my kubeconfig with my informations about oidc connexion : client_id, issuer-url, client-secret.

It seems to works but when i use kubelogin on a virtual machine linux, I have the following the message : open http://localhost:8000 for authentication

Unfornately, I can not access to localhost on my virtual machine and the vm doesnt have any browser.

I acces to my vm via mRemote and i would like to open a browser on my pc and not on the vm in localhost:8000.
I see in the following tutorial :

https://medium.com/@int128/kubectl-with-openid-connect-43120b451672

Manual

If you cannot access to localhost, instead open the following URL:

https://keycloak.example.com/auth/realms/hello/protocol/openid-connect/auth?client_id=kubernetes&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&scope=openid+email&state=********

Enter the code:

But i don't know how to use the manual mode.

Thanks for your help.

Add screencast

It would be nice if there is a screencast showing the login flow.

Skip login if current credentials are valid

I want to have a flow where I have a alias that switches my context and does a login to assure my credentials are correct, but I also don't want it to do anything if my credentials are already valid.

I wrote this for Okta and it essentially does the same thing, but your tool is a kubectl plugin and works better in general. https://github.com/sstarcher/k8s-auth

I would be willing to put in a PR for this feature if you will accept it.

oidc-login fails on WIndows with kubectl oidc-login not supported by windows

Dear all

After successfuly installed on Windows 10 Pro x_64 ๐Ÿ‘

krew info oidc-login
NAME: oidc-login
URI: https://github.com/int128/kubelogin/releases/download/v1.14.3/kubelogin_windows_amd64.zip
SHA256: bb961cff99b921060a070d2549b419b87697c1f0ecdefe043af54b2ee51a1b81
VERSION: v1.14.3
HOMEPAGE: https://github.com/int128/kubelogin
DESCRIPTION:
This is a kubectl plugin for Kubernetes OpenID Connect (OIDC) authentication.

Credential plugin mode

kubectl executes oidc-login before calling the Kubernetes APIs.
oidc-login automatically opens the browser and you can log in to the provider.
After authentication, kubectl gets the token from oidc-login and you can access the cluster.
See https://github.com/int128/kubelogin#credential-plugin-mode for more.

Standalone mode

Run kubectl oidc-login.
It automatically opens the browser and you can log in to the provider.
After authentication, it writes the token to the kubeconfig and you can access the cluster.
See https://github.com/int128/kubelogin#standalone-mode for more.

CAVEATS:

| You need to setup the OIDC provider, Kubernetes API server, role binding and kubeconfig.
| See https://github.com/int128/kubelogin for more.
/
PS C:\Users\TAACHSI2.krew> kubectl oidc-login
not supported by windows

Is is possible to have different permissions for different groups?

I was able to make this work perfectly with OneLogin, it is the same as KeyCloak and has the same idea of groups/scopes, and now I want to set different permissions for different groups using the same client:

My kops configuration looks like this:

    oidcGroupsClaim: groups
    oidcGroupsPrefix: 'oidc:'
    oidcIssuerURL: https://openid-connect.onelogin.com/oidc
    oidcUsernameClaim: email
    oidcUsernamePrefix: 'oidc:'

And my config looks like:

      config:
        client-id: XXXXX
        client-secret: XXXXX
        extra-scopes: profile,groups
        idp-issuer-url: https://openid-connect.onelogin.com/oidc

Yet, with or without the clusterrolebinding, I always get admin access. Am i missing something? How do I know to which user/group is it mapping? How do I get the JWT?

More info: https://www.onelogin.com/blog/changes-to-our-openid-connect-issuer
More info: https://developers.onelogin.com/openid-connect/scopes

Add token to the kube config file for kubernetes dashboard

Hi,

Kubernetes dashboard does not support auth-provider when trying to log in with the config file instead of a token, it needs a token at the same level as the auth-provider under user, e.g.:

- name: username
  user:
    auth-provider:
      config:
        client-id: id
        client-secret: secret
        id-token: token
        idp-issuer-url: https://accounts.google.com
        refresh-token: xx
      name: oidc
    token: token

Would be nice if the generated token could be added as well in order for the kubeconfig file to be usable to log in as well.

Work with Dex instead of keycloak?

I'm trying to switch from keycloak to dex, with a pretty simple dex configuration:

config:
  issuer: https://auth.my.domain
  storage:
    type: memory
  logger:
    level: debug
  staticClients:
    - id: kubernetes
      name: Kubelogin
      secret: kubernetes
      public: true
  enablePasswordDB: true
  staticPasswords:
    - email: [email protected]
      hash: [REDACTED]
      username: me
      userID: me

relevant .kube/config:

- name: dex
  user:
    auth-provider:
      config:
        client-id: kubernetes
        idp-issuer-url: https://auth.my.domain
      name: oidc

Upon using kubelogin with this setup, I get directed to the dex login page, I log in, get redirected to the OK page that kubelogin usually lands me at, but with the following log on CLI:

Open http://localhost:8000 for authentication
Opening in existing browser session.
[26416:26425:0602/232637.294657:ERROR:browser_process_sub_thread.cc(217)] Waited 5 ms for network service
Error: could not get a token from the OIDC provider: could not get a token: error while exchanging authorization code and token: oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"invalid_client","error_description":"Invalid client credentials."}

The OK page has code and state in the query string parameters. Running kubelogin with -v gives some additional information:

23:27:45.543896 WARNING: log may contain your secrets such as token or password
23:27:45.545056 Using the authentication provider of the user dex
23:27:45.545062 A token will be written to /home/me/.kube/config
23:27:45.545193 GET /.well-known/openid-configuration HTTP/1.1
Host: auth.my.domain
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

23:27:45.717122 HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: keep-alive
Content-Type: application/json
Date: Mon, 03 Jun 2019 03:27:45 GMT
Server: nginx/1.15.8
Vary: Accept-Encoding

2c1
{
  "issuer": "https://auth.my.domain",
  "authorization_endpoint": "https://auth.my.domain/auth",
  "token_endpoint": "https://auth.my.domain/token",
  "jwks_uri": "https://auth.my.domain/keys",
  "response_types_supported": [
    "code"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "groups",
    "profile",
    "offline_access"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "iat",
    "iss",
    "locale",
    "name",
    "sub"
  ]
}
0

Open http://localhost:8000 for authentication
Opening in existing browser session.
[26784:26793:0602/232746.633016:ERROR:browser_process_sub_thread.cc(217)] Waited 7 ms for network service
23:28:12.807176 POST /token HTTP/1.1
Host: auth.my.domain
User-Agent: Go-http-client/1.1
Content-Length: 103
Authorization: Basic a3ViZXJuZXRlczo=
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

code=uov7muno5wvtruwjcsur6wj7g&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8000
23:28:12.810014 HTTP/1.1 401 Unauthorized
Content-Length: 76
Connection: keep-alive
Content-Type: application/json
Date: Mon, 03 Jun 2019 03:28:12 GMT
Server: nginx/1.15.8

{"error":"invalid_client","error_description":"Invalid client credentials."}
23:28:12.810397 POST /token HTTP/1.1
Host: auth.my.domain
User-Agent: Go-http-client/1.1
Content-Length: 124
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

client_id=kubernetes&code=uov7muno5wvtruwjcsur6wj7g&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8000
23:28:12.812987 HTTP/1.1 401 Unauthorized
Content-Length: 76
Connection: keep-alive
Content-Type: application/json
Date: Mon, 03 Jun 2019 03:28:12 GMT
Server: nginx/1.15.8

{"error":"invalid_client","error_description":"Invalid client credentials."}
Error: could not get a token from the OIDC provider: could not get a token: error while exchanging authorization code and token: oauth2: cannot fetch token: 401 Unauthorized
Response: {"error":"invalid_client","error_description":"Invalid client credentials."}

Is there something fundamentally different with how dex does OAuth that isn't compatible with kubelogin?

Use the http.Client on refreshing token

It needs to wrap the context and use the http.Client on refreshing token as well. This causes long time due to failure of refreshing token.

// AuthenticateByCode performs the authorization code flow.
func (c *client) AuthenticateByCode(ctx context.Context, in adaptors.OIDCAuthenticateByCodeIn) (*adaptors.OIDCAuthenticateOut, error) {
if c.httpClient != nil {
ctx = context.WithValue(ctx, oauth2.HTTPClient, c.httpClient)
}

// Refresh sends a refresh token request and returns a token set.
func (c *client) Refresh(ctx context.Context, in adaptors.OIDCRefreshIn) (*adaptors.OIDCAuthenticateOut, error) {

See #122.

kubelogin doesn't work if I specify more than 1 configs in KUBECONFIG variable.

Hi,

Kubelogin doesn't like it, f I add more than 1 kubeconfig to KUBECONFIG.

export KUBECONFIG=/Users/userA/.kube/clustera-config:/Users/UserA/.kube/clusterb-config
kubelogin
2019/04/10 20:13:58 Reading /Users/userA/.kube/clustera-config:/Users/userA/.kube/clusterb-config
2019/04/10 20:13:58 Error: Could not read kubeconfig: open /Users/userA/.kube/clustera-config:/Users/userA/.kube/clusterb-config: no such file or directory

Support kubectl global options

kubectl has the following options:

% kubectl options
The following options can be passed to any command:

      --alsologtostderr=false: log to standard error as well as files
      --as='': Username to impersonate for the operation
      --as-group=[]: Group to impersonate for the operation, this flag can be repeated to specify multiple groups.
      --cache-dir='/Users/hidetake/.kube/http-cache': Default HTTP cache directory
      --certificate-authority='': Path to a cert file for the certificate authority
      --client-certificate='': Path to a client certificate file for TLS
      --client-key='': Path to a client key file for TLS
      --cluster='': The name of the kubeconfig cluster to use
      --context='': The name of the kubeconfig context to use
      --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
      --kubeconfig='': Path to the kubeconfig file to use for CLI requests.
      --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace
      --log-dir='': If non-empty, write log files in this directory
      --log-flush-frequency=5s: Maximum number of seconds between log flushes
      --logtostderr=true: log to standard error instead of files
      --match-server-version=false: Require server version to match client version
  -n, --namespace='': If present, the namespace scope for this CLI request
      --request-timeout='0': The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests.
  -s, --server='': The address and port of the Kubernetes API server
      --stderrthreshold=2: logs at or above this threshold go to stderr
      --token='': Bearer token for authentication to the API server
      --user='': The name of the kubeconfig user to use
  -v, --v=0: log level for V logs
      --vmodule=: comma-separated list of pattern=N settings for file-filtered logging

At this time kubelogin supports:

      --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
      --kubeconfig='': Path to the kubeconfig file to use for CLI requests.
  -v, --v=0: log level for V logs

As well as the following options may be valuable:

      --context='': The name of the kubeconfig context to use
      --user='': The name of the kubeconfig user to use
      --certificate-authority='': Path to a cert file for the certificate authority

authorization flow does not work if client-secret contains any special characters

Hello, i have encountered an issue when using any special symbols in client-secret, e.g.
! or +, the basic credentials generated by the authorization flow are invalid - it looks like base64 encoding issue:
when running the flow with -v=8
we see the following output:

13:07:50.619887 auth.go:93: Performing the authentication code flow
Open http://localhost:8000 for authentication
13:08:08.636807 transport.go:30: POST /oauth2/token HTTP/1.1
Host: <oidc.url>.com
User-Agent: Go-http-client/1.1
Content-Length: 110
Authorization: Basic VDAwMDAwMDpBYmNkMTIzNCUyMQ==
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

code=d5cbdc32c366541c07732f27a43db1b0&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8000
13:08:09.117823 transport.go:40: HTTP/1.1 401

the credentials used here are invalid:
Basic VDAwMDAwMDpBYmNkMTIzNCUyMQ==
those are decoded to T000000:Abcd1234%21 instead of T000000:Abcd1234!
and because of that we get 401 response.

our kubeconfig looks like this:
...
users:

  • name: shoot--devx-eldor--fsclientali
    user:
    auth-provider:
    config:
    client-id: T000000
    client-secret: Abcd1234!
    idp-issuer-url: https://<oidc.url>
    name: oidc

Cannot add OIDC CA cert

Kind: BUG

I suspect this might be a bug, but also might be some feature. :) I am using self signed CA to generate SSL certs and Kubelogin fails to add CA certificate from file for Keycloak auth service if it is defined the following way in the .kube\config:

UPDATE: Seems this is an issue only for Windows environment. kubelogin for Linux environments works as expected.

- name: cluster.local
  user:
    auth-provider:
      config:
        client-id: kubernetes
        client-secret: UUID
        id-token: ****
        idp-certificate-authority: C:\Users\Administrator\.kube\cluster.local.crt
        idp-issuer-url: https://keycloak.cust.lan/auth/realms/kubernetes
        refresh-token: ******
      name: oidc

Kubelogin throws the following error:

PS C:\Users\Administrator> kubelogin
2018/10/25 15:41:38 Reading ~/.kube/config
2018/10/25 15:41:38 Using current-context: cluster.local
2018/10/25 15:41:38 Error: Could not configure TLS: Could not append CA certificate from C:\Users\Administrator\.kube\cluster.local.crt

However if I define cert file the this way, then kubelogin works:

auth-provider-arg: idp-certificate-authority=C:\Users\Administrator\.kube\cluster.local.crt

Configuration file is generated via kubectl and I have not been successful to insert it to .kube\config in the above format. I would prefer not to edit config file and have a way to script initial config.

kubectl config set-credentials $CLUSTER_NAME `
  --auth-provider oidc `
  --auth-provider-arg idp-issuer-url=$KEYCLOAK_ADDRESS/auth/realms/kubernetes `
  --auth-provider-arg client-id=$CLIENT_ID `
  --auth-provider-arg idp-certificate-authority=$TARGETDIR\$CLUSTER_NAME.crt `
  --auth-provider-arg client-secret=$CLIENT_SECRET 

[krew] Distribute with license

๐Ÿ‘‹ Hello, maintainer of the kubectl plugin manager krew here.

Thank you for your commitment to open source by making this plugin available via krew!

Krew wants to give credit where credit is due by installing the proper license file for the plugins it distributes. However, your plugin was found to not contain any license file. We wanted to remind you that if you're using a license such as Apache 2.0, you should be bundling your LICENSE file with your pluginโ€™s distributions.

What do you have to do?

  • Please ensure your GitHub repository has a license file.
  • Make sure your archive file (.tar.gz or .zip) contains the license file.
  • Please submit a pull-request to krew-index and update the files: section to copy the file to the installation directory. Have a look at this PR for an example: https://github.com/kubernetes-sigs/krew-index/pull/314/files

If you need further assistance, don't hesitate to ask for help.

client-go credential plugin is slow compared to running as a command

Using kubelogin in client-go mode is very slow when compared to simply using the kubelogin command to generate the kubeconfig.

Consider 2 users:

- name: grunt
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - oidc-login
      - get-token
      - --oidc-issuer-url=https://<URL>/auth/realms/master
      - --oidc-client-id=kubernetes
      - --oidc-client-secret=<SECRET>
      - --certificate-authority=./kube-ca.pem
      command: kubectl
      env: null
- name: grunt-manual
  user:
    auth-provider:
      config:
        client-id: kubernetes
        client-secret: <SECRET>
        extra-scopes: groups
        id-token: <ID_TOKEN>
        idp-certificate-authority: ./kube-ca.pem
        idp-issuer-url: https:/<URL>/auth/realms/master
        refresh-token: <REFRESH_TOKEN>
      name: oidc

grunt:

> time (kcl get pods)
Open http://localhost:18000 for authentication
[17173:17192:0729/164900.154984:ERROR:browser_process_sub_thread.cc(221)] Waited 3 ms for network service
You got a valid token until 2019-07-29 16:50:00 -0400 EDT
Unable to connect to the server: getting credentials: decoding stdout: couldn't get version/kind; json parse error: json: cannot unmarshal string into Go value of type struct { APIVersion string "json:\"apiVersion,omitempty\""; Kind string "json:\"kind,omitempty\"" }
( kubectl get pods; )  0.12s user 0.05s system 5% cpu 3.297 total

> time (kcl get pods)
No resources found.
( kubectl get pods; )  0.14s user 0.03s system 7% cpu 2.173 total

...after token expires and refresh token is needed

> time (kcl get pods)
Open http://localhost:18000 for authentication
[20058:20085:0729/165124.847344:ERROR:browser_process_sub_thread.cc(221)] Waited 9 ms for network service
You got a valid token until 2019-07-29 16:52:25 -0400 EDT
Unable to connect to the server: getting credentials: decoding stdout: couldn't get version/kind; json parse error: json: cannot unmarshal string into Go value of type struct { APIVersion string "json:\"apiVersion,omitempty\""; Kind string "json:\"kind,omitempty\"" }
( kubectl get pods; )  0.18s user 0.01s system 6% cpu 2.999 total

grunt-manual:

> kubelogin --user -grunt-manual --certificate-authority kube-ca.pem
Open http://localhost:18000 for authentication
[14214:14242:0729/164628.365946:ERROR:browser_process_sub_thread.cc(221)] Waited 3 ms for network service
Opening in existing browser session.
You got a valid token until 2019-07-29 16:47:29 -0400 EDT

> time (kcl get pods)
No resources found.
( kubectl get pods; )  0.06s user 0.02s system 9% cpu 0.828 total

...after token expires and refresh token is needed

> time (kcl get pods)
No resources found.
( kubectl get pods; )  0.12s user 0.02s system 12% cpu 1.047 total

TL;DR

Time to issue a command.

Command Time without refresh (s) Time with refresh (s)
grunt 2.173s 2.999s
grunt-manual 0.828s 1.047s
how much slower? 162% 186%

Debug output groups the user belongs in

We have a common troubleshooting issue where a user does not have the access they believe they should have. We go to our Oauth provider and they tell us the groups are correct. It would be helpful if when setting -v > 0 that it would output the extra scopes that are provided.

Support of Implicit Flow

The IdP product used by us does not support public OIDC clients. This result in the situation that we need to distribute client-id and client-secret with the kubeconfig to workstations. This can be considered as a security issue.

Is the implicit flow supported by kubelogin or ist it planned?

OIDC error: invalid_grant error

After kubelogin upgrade to v1.12.0 I've tried to authorize to my K8S cluster running with Dex without opening a browser but failed with the following error:
{"error":"invalid_grant"}
error: error while the resource owner password credentials grant flow: could not get a token: oauth2: cannot fetch token: 400 Bad Request

Working with Browser works fine!

Full log:
โ‡’ kubelogin --context staging --insecure-skip-tls-verify --skip-open-browser --username test -v4
14:52:01.575730 WARNING: log may contain your secrets such as token or password
14:52:01.578762 Using the authentication provider of the user test@staging
14:52:01.578783 A token will be written to /Users/test/.kube/config
14:52:01.578791 Loading the certificate /Users/test/.ssh/staging-dex-ca.crt
Password:
14:52:05.922742 GET /dex/.well-known/openid-configuration HTTP/1.1
Host: staging-kubernetes-masters.service:32000
User-Agent: Go-http-client/1.1
Accept-Encoding: gzip

14:52:06.761844 HTTP/1.1 200 OK
Content-Length: 861
Content-Type: application/json
Date: Thu, 20 Jun 2019 11:52:06 GMT

{
"issuer": "https://staging-kubernetes-masters.service:32000/dex",
"authorization_endpoint": "https://staging-kubernetes-masters.service:32000/dex/auth",
"token_endpoint": "https://staging-kubernetes-masters.service:32000/dex/token",
"jwks_uri": "https://staging-kubernetes-masters.service:32000/dex/keys",
"response_types_supported": [
"code"
],
"subject_types_supported": [
"public"
],
"id_token_signing_alg_values_supported": [
"RS256"
],
"scopes_supported": [
"openid",
"email",
"groups",
"profile",
"offline_access"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic"
],
"claims_supported": [
"aud",
"email",
"email_verified",
"exp",
"iat",
"iss",
"locale",
"name",
"sub"
]
}
14:52:06.763737 POST /dex/token HTTP/1.1
Host: staging-kubernetes-masters.service:32000
User-Agent: Go-http-client/1.1
Content-Length: 114
Authorization: Basic xxxxxxxxxxxxxxxxxxxx
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

grant_type=password&password=xxxxxxx&scope=offline_access+openid+profile+email+groups+openid&username=test
14:52:06.971080 HTTP/1.1 400 Bad Request
Content-Length: 25
Content-Type: application/json
Date: Thu, 20 Jun 2019 11:52:07 GMT

{"error":"invalid_grant"}
14:52:06.971377 POST /dex/token HTTP/1.1
Host: staging-kubernetes-masters.service:32000
User-Agent: Go-http-client/1.1
Content-Length: 160
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip

client_id=xxxxxxxxx&client_secret=xxxxxxxxxx&grant_type=password&password=xxxxxxxxx&scope=offline_access+openid+profile+email+groups+openid&username=test
14:52:07.178048 HTTP/1.1 400 Bad Request
Content-Length: 25
Content-Type: application/json
Date: Thu, 20 Jun 2019 11:52:07 GMT

{"error":"invalid_grant"}
error: error while the resource owner password credentials grant flow: could not get a token: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant"}

groups claim not work.

Hi guys,

I tried kubelogin for my kube cluster with keycloak, but I have encountered some problems.

I setup keycloak client as follows:
image

Then I assigned the user "test" with "admin" role in "kubernetes" client, which is as follows:
image

Then I tried login with test, get a JWT with the claim:

echo eyJqdGkiOiI5YTM4OTUwZi0xODE3LTQxNGItYmM3MS00MGMzOTU2ZWYzYTEiLCJleHAiOjE1NjM3Nzg2OTEsIm5iZiI6MCwiaWF0IjoxNTYzNzc4MzkxLCJpc3MiOiJodHRwczovLzE3Mi4xNi4xMDUuMTo4MDgyL2F1dGgvcmVhbG1zL2hkbHMiLCJhdWQiOiJrdWJlcm5ldGVzIiwic3ViIjoiZTExZmQ1ODYtZTNiYS00YmNlLWFkOWQtM2E4MjZjNmRiYTk1IiwidHlwIjoiSUQiLCJhenAiOiJrdWJlcm5ldGVzIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiY2UxZmRmOWYtYzNlNS00MWE1LWE3MjUtZmE3NDdiNDVjZDdlIiwiYWNyIjoiMSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZ3JvdXBzIjoiW2t1YmVybmV0ZXM6YWRtaW5dIiwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9|base64 -D
{"jti":"9a38950f-1817-414b-bc71-40c3956ef3a1","exp":1563778691,"nbf":0,"iat":1563778391,"iss":"https://172.16.105.1:8082/auth/realms/hdls","aud":"kubernetes","sub":"e11fd586-e3ba-4bce-ad9d-3a826c6dba95","typ":"ID","azp":"kubernetes","auth_time":0,"session_state":"ce1fdf9f-c3e5-41a5-a725-fa747b45cd7e","acr":"1","email_verified":false,"groups":"[kubernetes:admin]","preferred_username":"test"}

But when I use kubectl get po , I got the error:

# kubectl  get po
Error from server (Forbidden): pods is forbidden: User "test" cannot list resource "pods" in API group "" in the namespace "default"

My apiserver settings are:

    - --oidc-issuer-url=https://172.16.105.1:8082/auth/realms/hdls
    - --oidc-client-id=kubernetes
    - --oidc-username-claim=preferred_username
    - --oidc-username-prefix=-
    - --oidc-groups-claim=["groups"]
    - --oidc-groups-prefix=-

ClusterRolebinding :

$ kubectl get clusterrolebinding keycloak-admin-group -oyaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"name":"keycloak-admin-group"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"cluster-admin"},"subjects":[{"kind":"Group","name":"manager"},{"kind":"Group","name":"kubernetes:admin"},{"kind":"User","name":"hdls"}]}
  creationTimestamp: "2019-07-16T08:12:17Z"
  name: keycloak-admin-group
  resourceVersion: "4536867"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/keycloak-admin-group
  uid: 6d2eb87e-a7a1-11e9-9539-005056b40224
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: kubernetes:admin

My kubernetes version:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.0", GitCommit:"641856db18352033a0d96dbc99153fa3b27298e5", GitTreeState:"clean", BuildDate:"2019-03-26T00:04:52Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.1", GitCommit:"b7394102d6ef778017f2ca4046abbaa23b88c290", GitTreeState:"clean", BuildDate:"2019-04-08T17:02:58Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}

I wanna know what's wrong with my operation or did I miss something?

Thankyou!

Wrap kubectl and login transparently

When the token has expired, kubectl shows the following error:

% kubectl get nodes
Unable to connect to the server: failed to refresh token: oauth2: cannot fetch token: 400 Bad Request
Response: {"error":"invalid_grant","error_description":"Refresh token expired"}

It would be nice if we just run kubectl and transparently it logins, like:

% kubectl get nodes
Open http://localhost:8000 for authentication
You got a valid token until 2019-05-18 10:28:51 +0900 JST
Updated ~/.kubeconfig
NAME                                          STATUS   ROLES    AGE   VERSION
ip-172-20-36-128.us-west-2.compute.internal   Ready    node     16d   v1.11.9
ip-172-20-41-128.us-west-2.compute.internal   Ready    master   9d    v1.11.9

Implementation

Use an alias like:

alias kubectl='kubelogin --kubectl --'

and kubectl get nodes will be run as:

kubelogin --kubectl -- get nodes

You can set the options as well.

alias kubectl='kubelogin --listen-port=20000 --kubectl --'

Note that it needs to parse the following options in extra args:

      --kubeconfig string              Path to the kubeconfig file
      --context string                 The name of the kubeconfig context to use
      --user string                    The name of the kubeconfig user to use. Prior to --context
      --certificate-authority string   Path to a cert file for the certificate authority
      --insecure-skip-tls-verify       If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
  -v, --v int                          If set to 1 or greater, it shows debug log

Differences to the login use case:

  • If the token is valid, do not show anything and just execute kubectl.
  • If the current authentication provider does not exist, do not show error.

Credential plugin mode & Resource owner password credentials grant flow

Credential plugin mode & Resource owner password credentials grant flow

Hello everyone,
the credential plugin mode for kubelogin is very nice. We plan to provide a skeleton of kubeconfig to all K8S OIDC users, but without defining --username in the kubeconfig.

We like OIDC K8S users to run "kubectl get pods" and then the resource owner password credentials grant flow should be triggered (instead the browser based flow)

Is there a possibility to trigger the resource owner password credentials grant flow with an option explicitly? Without defining --username, the normal browser based flow will be triggered. Setting --username (without) a user causes an error.

Thanks

error: You must be logged in to the server (Unauthorized)

I followed the Keycloak documentation, but cant really seem to make it work.
Keycloak is setup as pr. the docs, and when I run below command, it looks like I'm getting the response that I should.

kubectl oidc-login get-token -v1 \
 --oidc-issuer-url=https://keycloak-domain.org/auth/realms/kubernetes \
 --oidc-client-id=kubernetes \
 --oidc-client-secret=secret-goes-here
...
I0927 21:37:02.504991   32273 get_token.go:81] the ID token has the claim: groups=[kubernetes:admin]
I0927 21:37:02.504973   32273 get_token.go:81] the ID token has the claim: aud=kubernetes
I0927 21:37:02.505052   32273 get_token.go:81] the ID token has the claim: iss=https://keycloak-domain.org/auth/realms/kubernetes
I0927 21:37:02.505037   32273 get_token.go:81] the ID token has the claim: sub=uuid-goes-here
...

kube-api is configured.

$ cat /etc/kubernetes/manifests/kube-apiserver.yaml
...
    - --oidc-client-id=kubernetes
    - --oidc-groups-claim=groups
    - --oidc-issuer-url=https://keycloak-domain.org/auth/realms/kubernetes
    - --oidc-username-claim=email
...

I applied below to kubernetes.

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: keycloak-admin-group
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: Group
  name: kubernetes:admin

And added below to my kubeconfig file, which I have exported with export KUBECONFIG=./kubeconfig

...
contexts:
- context:
    cluster: green-bird-3416
    user: keycloak
  name: keycloak@green-bird-3416
current-context: keycloak@green-bird-3416
kind: Config
preferences: {}
users:
- name: keycloak
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubelogin
      args:
      - get-token
      - --oidc-issuer-url=https://keycloak-domain.org/auth/realms/kubernetes
      - --oidc-client-id=kubernetes
      - --oidc-client-secret=secret-goes-here

It generates a temp file at ~/.kube/cache/oidc-login/d721553ba91f6078f86a5cb2caa2f78eb4d27898b238dfad310b87f01ecdd117 with what looks like correct content.

But when i try and execute kubectl commands I just get:

$ kubectl get pods
You got a valid token until 2019-09-27 21:50:29 +0200 CEST
error: You must be logged in to the server (Unauthorized)

What am I missing here ?

Add an option to not log validation token message

Hi,
i'm using kubelogin in credential mode.
The problem i have is that kubelogin log message like You got a valid token until 2019-10-18 08:53:54 +0200 CEST in the terminal when it renew token.

When using tools like k9s i see this messages all around the screen when kubelogin renew the tokens.
Capture

Can you add an option to not display this messages in the terminal ?

"Could not get token from OIDC provider [...] Bad Gateway"

v1.8.2 works, but v1.9.0 does fail with

2019/04/08 17:16:58 Reading ~/.kube/config                                                                                                                                                                                                                                               
2019/04/08 17:16:58 Using current-context: kubernetes-dev-dev                                                                                                                                                                                                                            
2019/04/08 17:16:58 Using CA certificate: /home/xxx/.kube/xxx-root.crt
2019/04/08 17:16:58 Error: Could not get token from OIDC provider: Could not discovery the OIDC issuer: Get https://keycloak.our.domain.int/auth/realms/kubernetes/.well-known/openid-configuration: Bad Gateway

Another context works. Here the domain is https://keycloak.domain.int (without our). This simply uses another interface. However, the website is reachable under both domains.

It's odd that it works with v1.8.2 ..

Is there any more info I can post?

Run as a client-go credential plugin

Use https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins for transparently login feature, instead of wrapping kubectl.

Create a kubeconfig like:

users:
- name: keycloak
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: kubelogin
      args:
      - get-token

kubectl will execute kubelogin get-token before API calls. The command should return a token like the following json via standard output.

{
  "apiVersion": "client.authentication.k8s.io/v1beta1",
  "kind": "ExecCredential",
  "status": {
    "token": "YOUR_ID_TOKEN",
  }
}

Set certificate for OpenID provider?

I didn't see it in the documentation, is there a way to override the OpenID client side certificate?

$ kubelogin
2018/08/11 03:17:22 Reading /home/azurewraith/.kube/config
2018/08/11 03:17:22 Using current context: stage
2018/08/11 03:17:22 Authentication error: Could not access OIDC issuer: Get https://gitlab.domain/oauth/authorize/.well-known/openid-configuration: x509: certificate signed by unknown authority

I've tried idp-certificate-authority and idp-certificate-authority-data mentioned here to no avail.

PKCE authorization flow

Hi,

Is there any plan to support the PKCE authorization code flow? From the specs it looks interesting but not sure this is a widely adopted flow?

I know this is not supported on all providers but having to share a client secret in your kubeconfig with fellow developers seems a bit cumbersome? Unless there is another way of doing this that I'm not aware off?

Currently I've integrated our Kubernetes API with Okta(authorization code using client secret) and this work perfectly.

no groups from keycloak

Hi,

we have the Problem to retrieve groups from our keycloak/redat-sso (rh-sso version: 7.2.4) Server.

I have added the group kubernetes:admin and joined the group with my user. When i kubelogin all is fine, but the group ist not set

$ cat /etc/kubernetes/manifests/kube-apiserver.manifest  | grep oidc
    - --oidc-issuer-url=https://xxx/auth/realms/yyy
    - --oidc-client-id=kubernetes
    - --oidc-groups-claim=groups

kube config

current-context: admin-cluster.local                                                                   
 kind: Config                                                                                           
 preferences: {}                                                                                        
 users:                                                                                                 
 - name: admin-cluster.local                                                                            
   user:          
     auth-provider:  
       config:
         client-id: kubernetes
         client-secret: 123456
         extra-scopes: profile,groups                                                                            
         idp-issuer-url: https://xxx/auth/realms/yyy                                
       name: oidc

my encoded jwt is looking like this.

{
  "jti": "7b340f28-7593-42b7-83dc-5c562f5f3976",
  "exp": 1542377562,
  "nbf": 0,
  "iat": 1542377262,
  "iss": "https://xxx/auth/realms/yyy",
  "aud": "kubernetes",
  "sub": "53a86d82-96c8-44dc-81d4-96fe7a98247c",
  "typ": "ID",
  "azp": "kubernetes",
  "auth_time": 1542377106,
  "session_state": "4736ad4e-fbd0-46d3-b6bd-a0d5c86f47f1",
  "acr": "0",
  "name": "last, first",
  "preferred_username": "lalala",
  "given_name": "full",
  "family_name": "last",
  "email": "[email protected]"
}

Build error on windows_amd64 binary

https://circleci.com/gh/int128/kubelogin/314

VERSION=v1.12.0 goxzst -d dist/gh/ -o "kubelogin" -t "kubelogin.rb oidc-login.yaml" -- -ldflags "-X main.version=v1.12.0"
2019/06/05 13:04:42 GOOS=linux GOARCH=amd64 go build -o dist/gh/kubelogin_linux_amd64 -ldflags -X main.version=v1.12.0
2019/06/05 13:04:43 Creating dist/gh/kubelogin_linux_amd64.zip
2019/06/05 13:04:44 Creating dist/gh/kubelogin_linux_amd64.zip.sha256
2019/06/05 13:04:44 GOOS=darwin GOARCH=amd64 go build -o dist/gh/kubelogin_darwin_amd64 -ldflags -X main.version=v1.12.0
2019/06/05 13:04:52 Creating dist/gh/kubelogin_darwin_amd64.zip
2019/06/05 13:04:53 Creating dist/gh/kubelogin_darwin_amd64.zip.sha256
2019/06/05 13:04:53 GOOS=windows GOARCH=amd64 go build -o dist/gh/kubelogin_windows_amd64.exe -ldflags -X main.version=v1.12.0
go: downloading github.com/inconshreveable/mousetrap v1.0.0
go: extracting github.com/inconshreveable/mousetrap v1.0.0
# github.com/int128/kubelogin/adaptors/env
adaptors/env/env.go:22:33: cannot use syscall.Stdin (type syscall.Handle) as type int in argument to terminal.ReadPassword
2019/06/05 13:05:01 Error: error while build for the platform windows_amd64: error while cross build: go build error: error while exec: exit status 2

Feature request: Open browser automatically

Hi all,

Love the script, it'd be great if it could (optionally) open the browser automatically, with bonus points for closing it automatically as well - that'd make my login process really slick!

Improve the documents

I would be grateful if some English experts would correct the typo or reword the documents. Feel free to open pull requests!

Option for password grant flow instead of authorization code flow

KIND: Feature request

Currently kubelogin only supports the authorization code flow to retrieve ID tokens. This is helpful for interactive usage of human users where we can expect a web browser and typically an existing session with the OAuth server already (=> SSO). However, for automated scenarios where no browser is available, it would be helpful to be able to use the password grant flow instead.

I see the oauth2 library for go already supports the password grant flow (unfortunately with an compatibility to certain OAuth servers, but I hope this will be fixed - see golang/oauth2#320). That means, I assume it should be rather easy to add a command-line option to request the password grant flow as well as command-line parameters for user name and password.

Would this feature be generally appreciated? (before looking for the actual implementation)

Refresh token is blank

Kubelogin provides me with a token id but the refresh token is blank. I am using google for oidc.

Add fallback ports for local server

Currently kubelogin uses port 8000 for the local server but sometimes it conflicts with developer tools. It is good to support fallback ports. For example,

  1. If port 8000 is available, start the local server at 8000.
  2. If port 18000 is available, start the local server at 18000.
  3. Otherwise, fail.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.