Authentication
kobs hasn't any built in authentication mechanism. We recommend to run kobs behind a service like OAuth2 Proxy, which should handle the authentication of users.
Permissions
If the authentication / authorization middleware for kobs is enabled via the --api.auth.enabled
flag, we use the value from the --api.auth.header.user
and --api.auth.header.teams
header to authorize the user to access a plugin or Kubernetes resource. These headers should be set by a service like the OAuth2 Proxy like it is shown in the following examples.
The values from the headers are then used to get a User CR or a Team CR. If the user is part of multiple teams or when the permissions are set via the User CR and the Team CR, we merge all the permissions, so that the user can access all plugins and resources which are allowed for the user / teams.
Examples
The following two examples show how you can setup kobs with an OAuth2 Proxy infront using the NGINX Ingress Controller or Istio. Before you are looking into the examples, make sure you have setup your prefered OAuth Provider. We will use Google as our OAuth Provider in the following, which requires a Client ID and a Client Secret.
We are installing kobs into a namespace named kobs
using the provided Helm Chart. It will be available at demo.kobs.io, so keep in mind that you have to adjust the domain for your setup.
NGINX Ingress Controller
In the first step we have to create a Deployment, Service and Ingress for the OAuth2 Proxy. With the example wich can be found in the following we are exposing the OAuth2 Proxy via the oauth2-proxy.kobs.io domain. We are also setting all flags and secrets to use Google as our OAuth Provider and the --set-authorization-header
and --set-xauthrequest
flags to pass the email address of the authenticated user to kobs.
OAuth2 Proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: kobs
image: quay.io/oauth2-proxy/oauth2-proxy:v7.1.2
args:
- --provider=google
- --skip-provider-button=true
- --oidc-issuer-url=https://accounts.google.com
- --upstream=static://200
- --http-address=0.0.0.0:4180
- --email-domain=kobs.io
- --cookie-domain=.kobs.io
- --whitelist-domain=.kobs.io
- --set-authorization-header=true
- --set-xauthrequest=true
env:
# For the sake of simplicity we directly setting the Client ID and Client Secret as value. In a production
# environment you should set the values for these environment variables from a secret.
- name: OAUTH2_PROXY_CLIENT_ID
value: <GOOGLE_CLIENT_ID>
- name: OAUTH2_PROXY_CLIENT_SECRET
value: <GOOGLE_CLIENT_ID>
# The Cookie Secret can be generated using the following command:
# python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(16)).decode())'
- name: OAUTH2_PROXY_COOKIE_SECRET
value: 7jctnRZlsQRSFaX76LK53w==
- name: OAUTH2_PROXY_COOKIE_NAME
value: kobs-demo
ports:
- containerPort: 4180
name: http
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
spec:
type: ClusterIP
selector:
app: oauth2-proxy
ports:
- name: http
port: 4180
protocol: TCP
targetPort: http
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
annotations:
cert-manager.io/cluster-issuer: letsencrypt
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: oauth2-proxy.kobs.io
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: http
path: /
tls:
- hosts:
- oauth2-proxy.kobs.io
secretName: oauth2-proxy-cert
When the OAuth2 Proxy is running we can install kobs with the following values file. It will use all the default values from the Helm chart and just enables and configures the Ingress for kobs:
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/auth-url: https://oauth2-proxy.kobs.io/oauth2/auth
nginx.ingress.kubernetes.io/auth-signin: https://oauth2-proxy.kobs.io/oauth2/start?rd=https://demo.kobs.io
nginx.ingress.kubernetes.io/auth-response-headers: 'X-Auth-Request-Email'
nginx.ingress.kubernetes.io/configuration-snippet: |
auth_request_set $email $upstream_http_x_auth_request_email;
add_header X-Auth-Request-Email $email;
hosts:
- demo.kobs.io
tls:
- secretName: kobs-cert
hosts:
- demo.kobs.io
When you save the values from above in a file called values.yaml
, you can run the following command to install kobs:
helm upgrade --install kobs kobs/kobs -f values.yaml
Istio
In the first step we have to create a Deployment and Service the OAuth2 Proxy.
OAuth2 Proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: oauth2-proxy
spec:
replicas: 1
selector:
matchLabels:
app: oauth2-proxy
template:
metadata:
labels:
app: oauth2-proxy
spec:
containers:
- name: kobs
image: quay.io/oauth2-proxy/oauth2-proxy:v7.1.2
args:
- --provider=google
- --skip-provider-button=true
- --oidc-issuer-url=https://accounts.google.com
- --upstream=static://200
- --http-address=0.0.0.0:4180
- --email-domain=kobs.io
- --cookie-domain=.kobs.io
- --whitelist-domain=.kobs.io
- --set-authorization-header=true
- --set-xauthrequest=true
env:
# For the sake of simplicity we directly setting the Client ID and Client Secret as value. In a production
# environment you should set the values for these environment variables from a secret.
- name: OAUTH2_PROXY_CLIENT_ID
value: <GOOGLE_CLIENT_ID>
- name: OAUTH2_PROXY_CLIENT_SECRET
value: <GOOGLE_CLIENT_ID>
# The Cookie Secret can be generated using the following command:
# python -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(16)).decode())'
- name: OAUTH2_PROXY_COOKIE_SECRET
value: 7jctnRZlsQRSFaX76LK53w==
- name: OAUTH2_PROXY_COOKIE_NAME
value: kobs-demo
ports:
- containerPort: 4180
name: http
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: oauth2-proxy
spec:
type: ClusterIP
selector:
app: oauth2-proxy
ports:
- name: http
port: 4180
protocol: TCP
targetPort: http
When the OAuth2 Proxy is running we have to define the external authorizer that is allowed to be used in the mesh config. This is currently defined in the extension provider in the mesh config.
meshConfig:
extensionProviders:
- name: oauth2-proxy
envoyExtAuthzHttp:
service: oauth2-proxy.kobs.svc.cluster.local
port: "4180"
includeHeadersInCheck: ["authorization", "cookie"]
headersToUpstreamOnAllow: ["authorization", "x-auth-request-email", "x-auth-request-groups"]
The external authorizer is now ready to be used by the authorization policy.
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: kobs
spec:
selector:
matchLabels:
app.kubernetes.io/instance: kobs
app.kubernetes.io/name: kobs
action: CUSTOM
provider:
name: oauth2-proxy
rules:
- to:
- operation:
hosts:
- "*.kobs.io"
notPaths:
- "/oauth2*"
Now we have to adjust the istio
section in the kobs Helm chart. In contrast to the NGINX Ingress Controller example we do not create an additional Ingress / VirtualService for the OAuth2 Proxy. Instead the OAuth2 Proxy is exposed on the same domain as kobs via an additiona route:
istio:
virtualService:
enabled: true
gateways:
- istio-system/istio-default-gateway
hosts:
- demo.kobs.io
timeout: 3600s
additionalRoutes:
- match:
- uri:
prefix: /oauth2
route:
- destination:
host: oauth2-proxy.kobs.svc.cluster.local
port:
number: 4180
timeout: 60s
When you save the values from above in a file called values.yaml
, you can run the following command to install kobs:
helm upgrade --install kobs kobs/kobs -f values.yaml