Dex is a lightweight and minimal OpenID Connect (OIDC) provider designed for simple and self-hosted authentication setups. It is easy to deploy, integrates well with reverse proxies such as Traefik, and provides centralized authentication for applications like Pangolin without the complexity and resource overhead of larger identity platforms.
This guide shows a working setup for integrating Dex as the OIDC provider for Pangolin behind Traefik.
Architecture
Example setup:
Internet
↓
Traefik
├── Pangolin
└── Dex
Example domains:
Dex:
https://dex.example.com
Pangolin:
https://pangolin.example.com
Dex Configuration
Example config.yaml:
issuer: https://dex.example.com
storage:
type: memory
web:
http: 0.0.0.0:5556
staticClients:
- id: pangolin
name: Pangolin
secret: CHANGE_ME
redirectURIs:
- https://pangolin.example.com/auth/idp/5/oidc/callback
staticPasswords:
- email: admin@example.com
hash: "$2y$10$aQKUyEGDvtFl2SiAlKdpIevZlh90nI/0Hq0W1GuqiXIeTstk/O/8m"
Traefik dynamic_config.yml
Dex needs to be exposed directly through Traefik and should not be routed through Pangolin’s protected authentication flow. Add the following to Pangolin’s config/traefik/dynamic_config.yml:
http:
routers:
dex:
entryPoints:
- websecure
rule: "Host(`dex.example.com`)"
service: dex-service
tls:
certResolver: letsencrypt
services:
dex-service:
loadBalancer:
servers:
- url: "http://dex:5556"
This assumes:
- Dex container name is
dex - Dex listens on port
5556 - Dex and Traefik share the same Docker network
Pangolin OIDC Configuration
Configure Pangolin with the following values:
Client ID:
pangolin
Client Secret:
CHANGE_ME
Authorization URL:
https://dex.example.com/auth
Token URL:
https://dex.example.com/token
Identifier Path:
email
Email Path (Optional):
email
Name Path (Optional):
name
Scopes:
openid profile email
It is important that Identifier Path is set to email. This setup will not work using the default sub path.
Internal DNS Resolution
The Pangolin container must be able to resolve the Dex hostname internally. This helps avoid hairpin NAT or internal DNS resolution issues when Pangolin attempts to reach Dex through its public domain during the OIDC token exchange.
Add this to the Pangolin service in compose.yml:
extra_hosts:
- "dex.example.com:192.168.100.10"
Replace 192.168.100.10 with the internal IP address of the Traefik host. You can use Tailscale IP address if you want.
Verifying Dex Discovery
Verify the OIDC discovery endpoint:
https://dex.example.com/.well-known/openid-configuration
A working configuration should return endpoints similar to:
{
"issuer": "https://dex.example.com",
"authorization_endpoint": "https://dex.example.com/auth",
"token_endpoint": "https://dex.example.com/token",
"userinfo_endpoint": "https://dex.example.com/userinfo",
"jwks_uri": "https://dex.example.com/keys"
}
Security Notes
It is normal for Dex to be publicly accessible.
OIDC providers are expected to expose endpoints such as:
/.well-known/openid-configuration
/auth
/token
/userinfo
/keys
Security is enforced through:
- HTTPS
- client secrets
- redirect URI validation
- signed JWT tokens
- password hashing
Final Notes
Dex provides a lightweight and simple OIDC solution for self-hosted environments and works well with Pangolin once the DNS and claim mappings are configured correctly.