Skip to content

ericchiang/kube-oidc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenID Connect utilities for Kubernetes

Build Status

OpenID Connect and Kubernetes

OpenID Connect is an extension of OAuth2 that introduces ID Tokens, a signed JSON Web Token with standard claims representing users.

For example, OpenID Connect might return the following JWT:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjAyOWYyNjlmM2YwNmFmMWU5M2RhYzY3MDYzOTc3ZjcxM2E3N2YxOWUifQ.eyJhenAiOiIxMDc3ODQxODE2OTU5LWtrZGgwbHZxMWF1ODBxdjRndHVib3R2Z3M5YW00YTk1LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTA3Nzg0MTgxNjk1OS1ra2RoMGx2cTFhdTgwcXY0Z3R1Ym90dmdzOWFtNGE5NS5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMzYxMzAwMzc2NDQ5MDY0ODQ0OSIsImhkIjoicmVkaGF0LmNvbSIsImVtYWlsIjoiZWNoaWFuZ0ByZWRoYXQuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJPR0RPaklKOTJGa2F0REJvQ204eWRnIiwiZXhwIjoxNTI3MjAzOTQwLCJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJpYXQiOjE1MjcyMDAzNDAsIm5hbWUiOiJFcmljIENoaWFuZyIsInBpY3R1cmUiOiJodHRwczovL2xoNS5nb29nbGV1c2VyY29udGVudC5jb20vLUNzMmlIVFhpRVRzL0FBQUFBQUFBQUFJL0FBQUFBQUFBQUNNLzBRODVVaFppempnL3M5Ni1jL3Bob3RvLmpwZyIsImdpdmVuX25hbWUiOiJFcmljIiwiZmFtaWx5X25hbWUiOiJDaGlhbmciLCJsb2NhbGUiOiJlbiJ9.RjnTPN6RoQqL-lufUoAZxfaNVzET1uBZpszEodRZJlutYdThZHq_97bitG_qy5mIy07BmBPvr6lqOAeqBadENSkudhj6pQR9C3YD5Uyj9yTh7xp4CUx01Az6gsi8OCOgE1RCDRVwAialRhBlf3GCz4QBtBcwogTNVBoiDEwa5SKfopnwxsuKo_mBoHOjo9i_h-SakybrTe5ZJY_FuthtDli-s5LpFCuaiTLv6UpR84Zw9sNaxQ7Riiw1Mxya0xQXZnewhoJ8N2TwYlXuJJORvF0Pe2qjDwQmMEiqrv53E-f6C5pekGZip-ZtpDvZ7WmlNd5yGIbB8xvcH0RuHQLOoA

This ID Token holds claims such as the user's emal, username, and an expiration:

{
    "azp": "1077841816959-kkdh0lvq1au80qv4gtubotvgs9am4a95.apps.googleusercontent.com",
    "aud": "1077841816959-kkdh0lvq1au80qv4gtubotvgs9am4a95.apps.googleusercontent.com",
    "sub": "103613003764490648449",
    "hd": "redhat.com",
    "email": "[email protected]",
    "email_verified": true,
    "at_hash": "OGDOjIJ92FkatDBoCm8ydg",
    "exp": 1527203940,
    "iss": "https://accounts.google.com",
    "iat": 1527200340,
    "name": "Eric Chiang",
    "picture": "https://lh5.googleusercontent.com/-Cs2iHTXiETs/AAAAAAAAAAI/AAAAAAAAACM/0Q85UhZizjg/s96-c/photo.jpg",
    "given_name": "Eric",
    "family_name": "Chiang",
    "locale": "en"
}

Many providers have support for OpenID Connect, including:

Kubernetes can validate ID Tokens, but leaves login flows and other conviences as exercises to the user. This repo is intended to hold tools that fill in gaps and improve the experience of setting up SSO for Kubernetes clusters.

kube-oidc-login

kube-oidc-login is an OAuth2 client for generating user kubeconfig files. It logs in the user through an OpenID connect provider, then templates the returned ID Token into the kubeconfig:

kube-oidc-proxy

kube-oidc-proxy is an authenticating proxy for the Kubernetes API server. It authenticates OpenID Connect ID Tokens then impersonates the authenticated user to the API server.

Unlike other OpenID Connect solutions, kube-oidc-proxy doesn't require reconfiguration of the API server and works with any Kubernetes cluster out of the box.

Getting started

This guide requires:

  • A Kubernetes cluster (consider Minikube to run one locally)
  • An OAuth2 Google client credentials and a Google account
  • Go 1.10+

Clone this repo to your local GOPATH.

git clone https://github.com/ericchiang/kube-oidc.git $( go env GOPATH )/src/github.com/ericchiang/kube-oidc
cd $( go env GOPATH )/src/github.com/ericchiang/kube-oidc

Register a "Web application" OAuth client with Google and enter http://localhost:8080/login/callback as an authorized redirect URI. Set the OAuth client ID and secret as environment variables, as well as your email:

export GOOGLE_OAUTH2_CLIENT_ID="..."
export GOOGLE_OAUTH2_CLIENT_SECRET="..."
export USER_EMAIL="[email protected]"

The examples directory holds reference config files for kube-oidc-login and kube-oidc-proxy. Use sed to template these with the values defined above and generate self-signed certs for the proxy:

mkdir -p assets
mkdir -p secrets
sed "s/CLIENT_ID/$GOOGLE_OAUTH2_CLIENT_ID/g" examples/config-login.yaml > assets/config-login.yaml
sed "s/CLIENT_ID/$GOOGLE_OAUTH2_CLIENT_ID/g" examples/config-proxy.yaml > assets/config-proxy.yaml
echo -n "$GOOGLE_OAUTH2_CLIENT_SECRET" > secrets/client-secret
kubectl config view --raw=true > secrets/kubeconfig
make example-certs
sed "s/USER_EMAIL/$USER_EMAIL/g" examples/rbac.yaml > assets/rbac.yaml
kubectl apply -f assets/rbac.yaml

These commands should create the following directory structure:

$ tree assets/ secrets/
assets/
├── ca.csr
├── ca-key.pem
├── ca.pem
├── config-login.yaml
├── config-proxy.yaml
├── rbac.yaml
├── server.csr
├── server-key.pem
└── server.pem
secrets/
├── client-secret
└── kubeconfig

0 directories, 11 files

First, run kube-oidc-login:

make
./bin/kube-oidc-login serve assets/config-login.yaml

In another window run kube-oidc-proxy:

./bin/kube-oidc-proxy serve assets/config-proxy.yaml

Visit http://localhost:8080/ to login with Google. The email claim MUST match the USER_EMAIL environment variable defined above. If the values don't match, re-template and re-apply the RBAC manifest.

Use the downloaded kubeconfig to access the cluster through the OpenID Connect proxy:

$ kubectl --kubeconfig ~/Downloads/kubeconfig get pods -n kube-system
NAME                                                              READY     STATUS    RESTARTS   AGE
heapster-6f69d6797f-jvlg8                                         2/2       Running   3          5d
kube-apiserver-f94t9                                              1/1       Running   1          5d
kube-controller-manager-6d6db4c69d-jmhtj                          1/1       Running   2          5d
kube-dns-64cd9cc494-bqwvx                                         3/3       Running   3          5d
kube-flannel-jzqjz                                                2/2       Running   4          5d
kube-flannel-xvblb                                                2/2       Running   2          5d
kube-proxy-kgqth                                                  1/1       Running   1          5d
kube-proxy-rzqsk                                                  1/1       Running   1          5d
kube-scheduler-7b675dc9f7-jppj6                                   1/1       Running   1          5d
pod-checkpointer-h298b                                            1/1       Running   1          5d
pod-checkpointer-h298b-ip-10-0-22-42.us-west-1.compute.internal   1/1       Running   1          5d
$ kubectl --kubeconfig ~/Downloads/kubeconfig get nodes
Error from server (Forbidden): nodes is forbidden: User "[email protected]" cannot list nodes at the cluster scope