Set up local OIDC provider
Step 7 of the Kind deployment guide gates the console behind Traefik and oauth2-proxy, using Dex running inside the same kind cluster as the identity provider — so you can test the whole authentication flow with no cloud account and no real users. This page covers deploying Dex itself: do it after installing Traefik and before deploying oauth2-proxy.
Dex here uses in-memory storage and a static test password baked into its config. It is an IdP stand-in for development — never use this configuration anywhere real.
The issuer-URL problem
OIDC has one constraint that shapes the Dex setup: the issuer URL must be identical everywhere it’s seen.
- oauth2-proxy (running in-cluster) reaches Dex over a Kubernetes service name.
- Your browser reaches Dex to log in, and must land on the same issuer the token was minted for, or validation fails.
A service name like dex.flyte.svc.cluster.local isn’t resolvable from your browser; a
localhost URL isn’t resolvable from inside the cluster. The fix is to serve Dex under
the same host as Flyte (flyte.local) at a sub-path (/dex), and route to it
through Traefik. One URL — http://flyte.local/dex — works from both sides.
Dex configuration
The issuer is the through-Traefik URL; the two static clients are oauth2-proxy
(confidential, with a secret) and the Flyte CLI (public, for SDK login).
staticPasswords gives you a login with no external user store.
The Dex Helm chart renders whatever you pass under its config value into a Secret and
mounts it as config.yaml — so write the configuration nested under a top-level
config: key in a values file:
# dex-values.yaml
config:
issuer: http://flyte.local/dex
storage:
type: memory
web:
http: 0.0.0.0:5556
oauth2:
skipApprovalScreen: true # auto-approve, no consent screen in dev
staticClients:
# oauth2-proxy — confidential client (matches the secret you pass to oauth2-proxy in step 7)
- id: oauth2-proxy
name: oauth2-proxy
secret: oauth2-proxy-secret
redirectURIs:
- 'http://flyte.local/oauth2/callback'
- 'https://flyte.local/oauth2/callback' # console opened over TLS (websecure)
# Flyte CLI — public client for SDK/CLI PKCE login
- id: flytectl
name: 'Flyte CLI'
public: true
redirectURIs:
- 'http://localhost:53593/callback'
enablePasswordDB: true
staticPasswords:
# login: [email protected] / password
- email: "[email protected]"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
# bcrypt hash of the literal string "password" — see the note below
hash: "$2a$10$wi77Jcsjw08l416Q4./OCu6qNvYMaNSvA3Jbo30QeyZAvq9b4BSRK"hash must be a real bcrypt hashDex validates the hash at startup and crashes (CrashLoopBackOff) with
malformed bcrypt hash: hashedSecret too short to be a bcrypted password if it
isn’t a complete 60-character bcrypt string. The hash above is for password and
is known-good — but verify length 60 before pasting (echo -n "$HASH" | wc -c); a
char lost in transit looks fine and crashes Dex. To use a different password:
htpasswd -bnBC 10 "" 'your-password' | tr -d ':\n' | sed 's/^\$2y/\$2a/'Install Dex
helm repo add dex https://charts.dexidp.io
helm repo update
helm install dex dex/dex -n flyte -f dex-values.yamlThe chart already defines its own config volume, so mounting your own with
--set volumes[0].name=config collides with it (Duplicate value: "config"). Passing
the config under the chart’s config value, as above, is the supported path and avoids
the clash.
Confirm Dex came up:
kubectl -n flyte rollout status deploy/dex
kubectl -n flyte get svc dex # note the port (5556 by default)Route the issuer path through Traefik
Add an ingress so http://flyte.local/dex reaches the Dex service. This is what makes
the single issuer URL resolve from the browser:
# dex-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dex
namespace: flyte
spec:
ingressClassName: traefik
rules:
- host: flyte.local
http:
paths:
- path: /dex
pathType: Prefix
backend:
service:
name: dex
port:
number: 5556kubectl apply -f dex-ingress.yamlCheck discovery works through the host path — this is the URL oauth2-proxy will fetch:
# (with "127.0.0.1 flyte.local" in /etc/hosts and Traefik reachable on the node port)
curl -s http://flyte.local/dex/.well-known/openid-configuration | headA JSON document with "issuer":"http://flyte.local/dex" confirms Dex is reachable at
the issuer it advertises.
Next step
With Dex up and its issuer routable, return to the Kind deployment guide and
deploy oauth2-proxy pointed at http://flyte.local/dex.