A Kubernetes Operator (Go, controller-runtime) that dynamically assembles Dex configuration from Custom Resources.
Dex is installed separately via the official Dex Helm Chart. The operator watches for Custom Resources and generates two Secrets in the Dex namespace:
- Config-Secret — Full Dex configuration as YAML (Issuer, Storage, Web, CORS, gRPC, Logger, Expiry, Connectors, Static Clients)
- Env-Secret — All client secrets as environment variables (e.g.
GRAFANA_CLIENT_SECRET), attached to the Dex container viaenvFromand referenced in the config viasecretEnv
- Kubernetes cluster >= 1.25
- Helm >= 3.x
Dex is installed separately via the official Helm Chart. The key adjustment is that Dex must not use its own inline config but instead read the config and env secrets generated by the operator.
The following Helm values show the required changes:
# Tell the Dex chart to use an existing config secret managed by the operator
# instead of creating its own. The name must match DexInstallation .spec.configSecretName.
configSecret:
create: false
name: "dex-config"
# Inject all client/connector secrets as environment variables.
# The operator writes them to this secret; the config references them as $VAR.
# The name must match DexInstallation .spec.envSecretName.
envFrom:
- secretRef:
name: dex-envNote: The secret names (
dex-config/dex-env) must match theconfigSecretNameandenvSecretNamefields in theDexInstallationresource. With this setup the operator writes both secrets and any change is picked up live by the Dex deployment (or triggers a rollout restart whenrolloutRestart.enabled: trueis set on theDexInstallation).
helm repo add dex https://charts.dexidp.io
helm repo update
helm install dex dex/dex \
--namespace dex \
--create-namespace \
--values dex-values.yamlhelm repo add dex-operator https://guided-traffic.github.io/dex-operator
helm repo update
helm install dex-operator dex-operator/dex-operator \
--namespace dex-operator-system \
--create-namespacehelm repo update
helm upgrade dex-operator dex-operator/dex-operator \
--namespace dex-operator-systemhelm uninstall dex-operator --namespace dex-operator-systemdex.gtrfc.com/v1
| CRD | Description |
|---|---|
DexInstallation |
Global Dex config: Issuer, Storage, Web, CORS, gRPC, Logger, Expiry. Defines allowed namespaces and optional auto-restart. |
DexStaticClient |
OAuth2 static client referencing a DexInstallation and an existing Secret for client-id / client-secret. |
DexLDAPConnector |
LDAP identity provider connector |
DexGitHubConnector |
GitHub identity provider connector |
DexOIDCConnector |
Generic OIDC identity provider connector |
DexSAMLConnector |
SAML 2.0 identity provider connector |
DexGitLabConnector |
GitLab identity provider connector |
DexOAuth2Connector |
Generic OAuth2 identity provider connector |
DexGoogleConnector |
Google identity provider connector |
DexMicrosoftConnector |
Microsoft identity provider connector |
DexLinkedInConnector |
LinkedIn identity provider connector |
DexAuthProxyConnector |
AuthProxy connector |
DexBitbucketConnector |
Bitbucket identity provider connector |
DexLocalConnector |
Local (built-in) connector |
DexOpenShiftConnector |
OpenShift identity provider connector |
DexAtlassianCrowdConnector |
Atlassian Crowd connector |
DexGiteaConnector |
Gitea identity provider connector |
DexKeystoneConnector |
OpenStack Keystone connector |
A DexInstallation defines the global Dex configuration. The operator collects all associated connectors and static clients from allowed namespaces and writes the resulting configuration to the specified secrets.
apiVersion: dex.gtrfc.com/v1
kind: DexInstallation
metadata:
name: main
namespace: dex
spec:
issuer: https://dex.example.com
storage:
type: kubernetes
web:
http: 0.0.0.0:5556
logger:
level: info
format: json
oauth2:
skipApprovalScreen: true
responseTypes:
- code
expiry:
idTokens: 24h
signingKeys: 6h
configSecretName: dex-config
envSecretName: dex-env
allowedNamespaces:
- "*"
rolloutRestart:
enabled: true
deploymentName: dexA DexStaticClient represents an OAuth2 client registered with Dex. It references a DexInstallation and an existing Kubernetes Secret containing client-id and client-secret.
apiVersion: v1
kind: Secret
metadata:
name: grafana-oidc
namespace: monitoring
type: Opaque
stringData:
client-id: grafana
client-secret: my-super-secret
---
apiVersion: dex.gtrfc.com/v1
kind: DexStaticClient
metadata:
name: grafana
namespace: monitoring
spec:
installationRef:
name: main
namespace: dex
name: Grafana
secretRef:
name: grafana-oidc
clientIDKey: client-id
clientSecretKey: client-secret
redirectURIs:
- https://grafana.example.com/login/generic_oauth
allowedScopes:
- openid
- profile
- email
- groupsA DexLDAPConnector configures Dex to authenticate users against an LDAP directory (e.g. Active Directory, OpenLDAP).
apiVersion: v1
kind: Secret
metadata:
name: ldap-credentials
namespace: dex
type: Opaque
stringData:
bind-password: my-ldap-password
root-ca.pem: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
---
apiVersion: dex.gtrfc.com/v1
kind: DexLDAPConnector
metadata:
name: corporate-ldap
namespace: dex
spec:
installationRef:
name: main
namespace: dex
name: Corporate LDAP
host: ldap.example.com:636
bindDN: cn=serviceaccount,dc=example,dc=com
bindPWRef:
name: ldap-credentials
key: bind-password
rootCARef:
name: ldap-credentials
key: root-ca.pem
userSearch:
baseDN: ou=Users,dc=example,dc=com
filter: "(objectClass=person)"
username: sAMAccountName
idAttr: DN
emailAttr: mail
nameAttr: displayName
groupSearch:
baseDN: ou=Groups,dc=example,dc=com
filter: "(objectClass=group)"
userAttr: DN
groupAttr: member
nameAttr: cnA DexGitHubConnector enables authentication via GitHub OAuth. The GitHub OAuth app credentials are stored in a Kubernetes Secret.
apiVersion: v1
kind: Secret
metadata:
name: github-oauth
namespace: dex
type: Opaque
stringData:
client-id: my-github-client-id
client-secret: my-github-client-secret
---
apiVersion: dex.gtrfc.com/v1
kind: DexGitHubConnector
metadata:
name: github
namespace: dex
spec:
installationRef:
name: main
namespace: dex
name: GitHub
clientIDRef:
name: github-oauth
key: client-id
clientSecretRef:
name: github-oauth
key: client-secret
redirectURI: https://dex.example.com/callback
orgs:
- name: my-org
teams:
- developers
- platform
loadAllGroups: false
useLoginAsID: true- The operator watches all namespaces.
- On
DexInstallationreconciliation: all associated connectors and static clients from allowed namespaces are collected, the config YAML and env-secret are built, and the secrets are written to the Dex namespace. - On reconciliation of a client or connector: the referenced
DexInstallationis re-triggered. - Namespace whitelist validation on every client/connector.
- Optional rollout restart of the Dex deployment on config change.
# Build the manager binary
make build
# Run locally (requires a valid kubeconfig)
make run
# Generate CRDs and DeepCopy code
make generate-all
# Run linting
make lint
# Run tests
make test