Skip to main content
Version: main

Configuring OIDC with Dex and GitHub

In this guide we will show you how to enable users to login to the Weave GitOps dashboard by authenticating with their GitHub account.

This example uses Dex and its GitHub connector, and assumes Weave GitOps has already been installed on a Kubernetes clusters.

Pre-requisites

What is Dex?

Dex is an identity service that uses OpenID Connect to drive authentication for other apps.

Alternative solutions for identity and access management exist such as Keycloak.

Create Dex namespace

Create a namespace where Dex will be installed:

---
apiVersion: v1
kind: Namespace
metadata:
name: dex

Add credentials

There are a lot of options available with Dex, in this guide we will use the GitHub connector.

We can get a GitHub ClientID and Client secret by creating a new OAuth application.

GitHub OAuth configuration

kubectl create secret generic github-client \
--namespace=dex \
--from-literal=client-id=${GITHUB_CLIENT_ID} \
--from-literal=client-secret=${GITHUB_CLIENT_SECRET}

Deploy Dex

As we did before, we can use HelmRepository and HelmRelease objects to let Flux deploy everything.

---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: dex
namespace: dex
spec:
interval: 1m
url: https://charts.dexidp.io
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: dex
namespace: dex
spec:
interval: 5m
chart:
spec:
chart: dex
version: 0.6.5
sourceRef:
kind: HelmRepository
name: dex
namespace: dex
interval: 1m
values:
image:
tag: v2.31.0
envVars:
- name: GITHUB_CLIENT_ID
valueFrom:
secretKeyRef:
name: github-client
key: client-id
- name: GITHUB_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: github-client
key: client-secret
config:
# Set it to a valid URL
issuer: https://dex.dev.example.tld

# See https://dexidp.io/docs/storage/ for more options
storage:
type: memory

staticClients:
- name: 'Weave GitOps Core'
id: weave-gitops
secret: AiAImuXKhoI5ApvKWF988txjZ+6rG3S7o6X5En
redirectURIs:
- 'https://localhost:9001/oauth2/callback'
- 'https://0.0.0.0:9001/oauth2/callback'
- 'http://0.0.0.0:9001/oauth2/callback'
- 'http://localhost:4567/oauth2/callback'
- 'https://localhost:4567/oauth2/callback'
- 'http://localhost:3000/oauth2/callback'

connectors:
- type: github
id: github
name: GitHub
config:
clientID: $GITHUB_CLIENT_ID
clientSecret: $GITHUB_CLIENT_SECRET
redirectURI: https://dex.dev.example.tld/callback
orgs:
- name: weaveworks
teams:
- team-a
- team-b
- QA
- name: ww-test-org
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: dex.dev.example.tld
paths:
- path: /
pathType: ImplementationSpecific
tls:
- hosts:
- dex.dev.example.tld
secretName: dex-dev-example-tld
SSL certificate without cert manager

If we don't want to use cert manager, we can remove the related annotation and use our predefined secret in the tls section.

An important part of the configuration is the orgs field on the GitHub connector.

orgs:
- name: weaveworks
teams:
- team-a
- team-b
- QA

Here we can define groups under a GitHub organisation. In this example the GitHub organisation is weaveworks and all members of the team-a, team-b, and QA teams can authenticate. Group membership will be added to the user.

Based on these groups, we can bind roles to groups:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: wego-test-user-read-resources
namespace: flux-system
subjects:
- kind: Group
name: weaveworks:QA
namespace: flux-system
roleRef:
kind: Role
name: wego-admin-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: wego-admin-role
namespace: flux-system
rules:
- apiGroups: [""]
resources: ["secrets", "pods" ]
verbs: [ "get", "list" ]
- apiGroups: ["apps"]
resources: [ "deployments", "replicasets"]
verbs: [ "get", "list" ]
- apiGroups: ["kustomize.toolkit.fluxcd.io"]
resources: [ "kustomizations" ]
verbs: [ "get", "list", "patch" ]
- apiGroups: ["helm.toolkit.fluxcd.io"]
resources: [ "helmreleases" ]
verbs: [ "get", "list", "patch" ]
- apiGroups: ["source.toolkit.fluxcd.io"]
resources: ["buckets", "helmcharts", "gitrepositories", "helmrepositories", "ocirepositories"]
verbs: ["get", "list", "patch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "watch", "list"]

The same way we can bind cluster roles to a group:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: weaveworks:team-a
subjects:
- kind: Group
name: weaveworks:team-a
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io

Set up static user

For static user, add staticPasswords to the config:

spec:
values:
config:
staticPasswords:
- email: "admin@example.tld"
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"

Static user password can be generated with htpasswd:

echo password | htpasswd -BinC 10 admin | cut -d: -f2

OIDC login

Using the "Login with OIDC Provider" button:

Login page

We have to authorize the GitHub OAuth application:

GitHub OAuth page

After that, grant access to Dex:

Dex grant access

Now we are logged in with our GitHub user and we can see all resources we have access to:

UI logged in