# Using single-sign-on oauth2 across many sites in Kubernetes

- Link: https://www.agilicus.com/using-single-sign-on-oauth2-across-many-sites-in-kubernetes/
- Published: 2019-04-01T00:36:34+00:00
- Author: Don Bowman

You have a set of web resources (a kibana dashboard, a grafana dashboard, a few 
other misc ones). You are setting them all up with ‘basic’ auth because its simple,
and secretly hoping no-one guesses “MyS3cret”. You, my friend, are doing it wrong.
Let me explain. (see how to do this with Istio [here](https://www.agilicus.com/using-istio-openid-connect-oauth2-to-authorise/)).

It turns out there is a protocol called ‘oauth2’. You have probably seen this on
many sites (e.g. ‘sign in with Google’/’GitHub’ etc). As a consumer, you should 
always do that when you can. Its much better to have one strong setup (your Google
one) than many weak ones. When you ‘sign in with Google’ it doesn’t actually share
your password or profile, it just does authentication.

Now, how can we translate that into the misc set of web pages that we run in our
system? This is super simple but it wasn’t well documented and took me a bit to 
figure out how to do it well.

First, lets create a small yaml file, ‘oauth2-values.yaml’. Fill it in like so. 
You will need to get the clientID and clientSecret. I am using Google (so [https://console.cloud.google.com/apis/credentials](https://www.agilicus.com/using-istio-openid-connect-oauth2-to-authorise/)),
but there are other sites like GitHub, GitLab, etc you can use, and ample instructions
online for this. In the Google case, allow redirect URI of ‘_oauth2.\_\_MYDOMAIN\_\_/
oauth2/callback_‘

    ```wp-block-preformatted
    config:
      clientID: "xxxxx.apps.googleusercontent.com"
      clientSecret: "yyyyyyy"
      # Create a new cookieSecret with the following command
      # python -c 'import os,base64; print base64.b64encode(os.urandom(16))'
      cookieSecret: "zzzzz=="
      configFile: |-
        pass_basic_auth = false
        pass_access_token = true
        set_authorization_header = true
        pass_authorization_header = true

    image:
      repository: "quay.io/pusher/oauth2_proxy"
      tag: "v3.1.0"
      pullPolicy: "IfNotPresent"

    extraArgs:
      provider: "google"
      email-domain: "__MYDOMAIN__"
      cookie-domain: "__MYDOMAIN__"
      upstream: "file:///dev/null"
      http-address: "0.0.0.0:4180"

    ingress:
      enabled: true
      annotations:
        ingress.kubernetes.io/ssl-redirect: 'true'
        kubernetes.io/ingress.class: nginx
        kubernetes.io/tls-acme: "true"
        certmanager.k8s.io/cluster-issuer: letsencrypt
        nginx.ingress.kubernetes.io/proxy-body-size: 100m
        path: /
      hosts:
        - oauth2.__MYDOMAIN__
        - oauth2.__MYDOMAIN__
      tls:
        - secretName: oauth2-noc-tls
          hosts:
            - oauth2.__MYDOMAIN__
            - oauth2.__MYDOMAIN__
    ```

Now we are going to install an ‘oauth2 proxy’. We will run *1* for our entire domain,
and it will allow anyone with our domain to access.

    ```wp-block-preformatted
    helm install -f oauth2-values.yaml --name oauth2 --namespace oauth2 stable/oauth2-proxy
    ```

OK, now we just need to add 2 annotation lines to every ingress:

    ```wp-block-preformatted
     nginx.ingress.kubernetes.io/auth-signin: https://oauth2.__MYDOMAIN__/oauth2/start?rd=$http_host$request_uri
     nginx.ingress.kubernetes.io/auth-url: https://oauth2.__MYDOMAIN__/oauth2/auth
    ```

And boom we are done. I’m assuming you are already using the excellent cert-manager
so your site is TLS protected. Now you have strong sign-on, and, more usefuly, single-
sign-on.

The key is that ‘cookie-domain’ above. It means we are using a single oauth2-proxy
protecting the entire domain, and, once one site is signed in, all sites are signed
in. So great!

Even better, if you use Multi-Factor-Authenticaation it fits in with it. Rarely 
type a password again, prevent needing passwords for new sites, and be more secure.
What’s not to love!
