DEV Community

Atharva Chidambar Joshi
Atharva Chidambar Joshi

Posted on • Originally published at acjoshi.dev on

Getting started with OIDC and Dex with kind

  • this article covers how you can setup a local cluster in with kind (not rudely), the next one would cover Microsoft Oauth process.

OIDC?

  • Oauth2 is primarily a AUTHORIZATION protocol.(The capitalization is more a reminder to myself than the reader)
  • Open IDentity Connect is a AUTHENTICATION protocol that is built on top of Oauth2, effectively making it handle both.
  • OIDC is the reason why you get that shiny “Sign in with Google” or Microsoft, or Facebook button in different applications you see.

google-sign

What is Dex?

  • dex is an open source project that aims to simplify authentication for applications.
  • Imagine this, you only had to deal with OIDC once (Ideally never would be nice, but its never ideal is it) and someone else took care of every other OIDC providers.
  • Dex would talk to other OIDC providers and your application remains agnostic about the different providers, your application only knows about Dex and the tokens Dex gives.
  • Dex comes with a local installation too, which means that the source of truth for authentication is its own database, you can interact with this service via grpc calls.
  • You can configure the storage options as described here
  • Dex’s OIDC is the only protocol your application needs to support, the upstream connector can be anything, LDAP,SAML,OAUTH,here’s the exhaustive list. Connector is basically the place where Dex will go to for getting the user credentials verified. So your app only has to implement OIDC process for Dex, Dex will take care of the rest.

Why do I need dex?

  • Imagine this you have built your cool application and it has a standard login page that accepts email and password. But its 2025 now and you feel you need to ease the process by having a google sign in button.
  • So you set out on a journey to implement google Oauth2 by going to google console, registering your app, getting your client id and secret and start using it for your app.
  • Luck is on your side and your application is growing popular, now you want to on onboard facebook users. But oh no!! your application is hard coded with google endpoints for authentication, so you pile up some technical debt and hardcode your facebook endpoint.
  • As days pass you realise you maybe need Microsoft Oauth as well, and you finally realise maybe it was a bad idea to hard code facebook Oauth2, as your authentication endpoints keep increasing and it becomes a hassle to maintain dev,stage, and prod credentials of your application.

bunch-sign

But what is OIDC, technically?

  • Before i summarise briefly how an OIDC flow looks like, lets get on the same page about terminology for clarity.

  • Alright then lets get on already:

  • the id tokens look something like this:

jwt example

- jwt.io would be your goto page for your jwt needs.

  • NOTE:
    • never share your refresh tokens as that would mean client can keep refreshing their tokens till refresh tokens expire, which are usually long lived.
    • access tokens are for applications to access resources that are consented to be accessed by the user like email,or your google photos.

Local connector

  • local connector means that Dex will maintain its own database.
  • the process to setup connector mostly remains the same regardless of which Oauth2 provider you choose to go with, but the process would vary for LDAP,SAML connectors.
  • you would get client-id and client-secret, while choosing redirect url of your own liking and scopes that you might need.

Getting the tools

  • you would need these cli tools

  • You can find the code for all of this here

Architecture

  • We will deploy our Dex instance behind a Kong gateway in a kind cluster, reason being that Dex is built for production, so you’d follow similar patterns when you use it in your actual project.

  • once you understand how to deploy locally in kind, production is merely some endpoint changes away.

-

 ┌──────────────────────────────────────────────────────────────────────┐
│ Docker │
│ ┌──────────────┐ ┌─────────────────────────────────────┐ │
│ │ control-plane│ │worker node │ │
│ │ KinD │ │ ┌────┐ ┌────┐ ┌─────────┐ │ │
│ └──────────────┘ │ │KONG│ │DEX │ │POSTGRES │ │ │
│ │ └────┘ └────┘ └─────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────┘

- we will also use helmfile with format to deploy our application, for context this is like killing a mosquito with a nuke, because helmfile shines when you have a complex setup for your application, unlike our application, But we will still use this because its fun to learn complex things easily.

### Configurations

#### cluster config

- following helmfile describes the list of all the things kubernetes needs to install for our application.


Enter fullscreen mode Exit fullscreen mode


yaml
environments:
default:
values:

- values.yaml

repositories:

releases:

  • name: kong namespace: kong createNamespace: true chart: kong/kong version: ~2.51.0 # or latest stable, check via helm search repo kong/kong set:
  • name: ingressControllerCRDs value: false values:
  • kong-values.yaml

  • name: postgres
    namespace: postgres
    labels:
    app: postgres
    tier: core
    version: 16.0.3
    chart: oci://registry-1.docker.io/bitnamicharts/postgresql
    set:

  • name: nameOverride
    value: postgres

  • name: auth.database
    value: ps_db

  • name: auth.username
    value: {{ .Values.postgres.user }}

  • name: auth.password
    value: {{ .Values.postgres.pass }}

  • name: image.repository
    value: bitnamilegacy/postgresql

  • name: dex
    namespace: auth
    createNamespace: true
    chart: ./charts/dex
    values:

  • dex-values.yaml

  • name: backend
    namespace: auth
    createNamespace: false
    chart: ./charts/backend
    values:

  • backend-values.yaml
    needs:

  • auth/dex

  • name: frontend
    namespace: frontend
    createNamespace: true
    chart: ./charts/frontend
    values:

  • frontend-values.yaml


##### charts?

- For any application to be deployed in your cluster, you need charts, charts are yaml files of deployment, service, ingress at its minimum. They describe how your pod would be behaving in the cluster. Pod is where your docker container is hosted, effectively your app would be running in a pod.
  - Deployment is a yaml file that describes how much resources your application wants, resources could be pods, cpu
  - Service is an abstraction for the application that will run in a production.
  - Ingress is the biggest culprit for when your pod is running but your requests wont be processed, its because none of your request are actually going to the pod.
  - In ingress your incoming rules need to be setup explicitly, therefore your request never reached the pod if no ingress rules were defined.
- Here we’re telling `helmfile` that hey, please install dex, kong, frontend and backend apps, and their associated configurable values are present in the `value.yaml`.

#### dex config

Enter fullscreen mode Exit fullscreen mode


yaml

Dex chart values - matching charts/dex/values.yaml structure

global:
# Database configuration for Dex
database:
host: postgres.postgres.svc.cluster.local
port: 5432
ssl:
mode: disable
createDatabase: true
username: dex

# Database secret for password
databaseSecret:
name: postgres
key: password

# Ingress configuration
ingress:
ingressClassName: kong
host: localhost
controllerUrl: "http://dex-dex-server-http.auth.svc.cluster.local:5556" # this url is discoverable on the inside of cluster.
annotations: {}

Dex database name

database:
database: ps_db

HTTP port for Dex service

httpPort: 5556

GRPC port for internal communication

internalGrpcPort: 8082

Enable password database (local authentication)

enablePasswordDb: true

OAuth2 configuration

oauth2:
passwordConnector:
enable: true
value: local
responseTypes: ["code"]

Static passwords for local authentication

staticPasswords:

  • email: "admin-dex@example.com" hash: "JDJhJDEyJEwycXBiTjRjNThHTHd1YXo4Wnhoa2UvSzF1cHMvWnVyRnhvNU9iRnAxQWhILmllNGdUNXZD" # bcrypt hash of "password" username: "admin" userID: "1"

Additional static clients for OAuth2

additionalStaticClients:

Resource limits

resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"

Liveness probe configuration

livenessProbe:
enabled: true
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 5

Replica count

replicaCount: 1

Environment variables for dex container

dex:
env:

  • name: PASSWORD_ENV_VAR valueFrom: secretKeyRef: name: postgres key: password



## DEMO

![dex-local-login-demo](https://acjoshi.dev/images/dexLogin.gif)

- in the next article we will cover how you can onboard Microsoft Oauth2 with dex.
- _PS: AI was used for proof reading and ensuring technical accuracy but never to generate the sentences you read._
Enter fullscreen mode Exit fullscreen mode

Top comments (0)