5.3 KiB
5.3 KiB
Temporal OAuth2-Proxy Setup (Authentik OIDC)
Overview
Protects Temporal UI with Authentik OIDC authentication. Traffic flow:
Browser → Ingress (TLS) → oauth2-proxy (OIDC check) → temporal-web (internal)
↓
Redirects to Authentik login
↓
JWT cookie issued
↓
Forwards to temporal-web
Prerequisites
✅ Authentik OIDC provider temporal already exists with:
- Client ID:
temporal - Client Secret: stored in Kubernetes secret
temporal-oidc(key:clientSecret) - Redirect URI:
https://temporal.riotpiao.homelab.com/oauth2/callback
Secrets
The temporal-oidc secret must contain:
| Key | Value | Source |
|---|---|---|
clientSecret |
OAuth2 client secret from Authentik | Authentik → Applications → temporal |
cookieSecret |
Session encryption key (base64 32-byte) | Generate: openssl rand -base64 32 |
Check existing secret:
kubectl get secret -n temporal temporal-oidc
kubectl describe secret -n temporal temporal-oidc
If missing, create it:
# Get client secret from Authentik UI
# Applications → temporal → copy "Client Secret"
CLIENT_SECRET="..."
# Generate cookie secret
COOKIE_SECRET=$(openssl rand -base64 32)
# Create secret
kubectl create secret generic temporal-oidc \
-n temporal \
--from-literal=clientSecret="${CLIENT_SECRET}" \
--from-literal=cookieSecret="${COOKIE_SECRET}"
Deployment Steps
Step 1: Apply OAuth2-Proxy Manifests
kubectl apply -f k8s/temporal/oauth2-proxy.yaml
Verify:
kubectl get deploy -n temporal oauth2-proxy
kubectl logs -n temporal deploy/oauth2-proxy
Expected log:
[<timestamp>] [oauthproxy.go:...] Listening on 0.0.0.0:4180
Step 2: Apply OAuth2-Proxy Ingress
kubectl apply -f k8s/temporal/temporal-ingress-oauth2.yaml
Verify:
kubectl get ingress -n temporal
Expected:
NAME CLASS HOSTS ADDRESS PORTS AGE
temporal nginx temporal.riotpiao.homelab.com ... 80, 443 10s
Step 3: Test Access
-
Open Temporal UI (unauthenticated):
open https://temporal.riotpiao.homelab.comExpected: Redirects to Authentik login page
-
Login with Authentik credentials
- Username/email
- Password
- Should redirect back to
temporal.riotpiao.homelab.comand display UI
-
Verify auth:
# Check for oauth2_proxy cookie curl -v https://temporal.riotpiao.homelab.com 2>&1 | grep -i cookie -
Check oauth2-proxy logs:
kubectl logs -n temporal deploy/oauth2-proxy -fLook for:
[timestamp] [auth_test.go:...] Authentication successful
Troubleshooting
Redirect URI mismatch
Error in oauth2-proxy logs:
redirect_uri_mismatch: The redirect_uri does not match the one registered in Authentik
Fix:
- Verify Authentik application (Applications → temporal) has redirect URI:
https://temporal.riotpiao.homelab.com/oauth2/callback - Ensure HTTPS (not HTTP)
Missing secret
Error:
clientSecret: key not found in temporal-oidc secret
Fix:
kubectl get secret -n temporal temporal-oidc -o yaml
# If missing, create per "Secrets" section above
Cookie secret expiration
OAuth2-Proxy won't start if cookieSecret is empty or invalid.
Fix:
COOKIE_SECRET=$(openssl rand -base64 32)
kubectl patch secret temporal-oidc -n temporal \
-p "{\"data\":{\"cookieSecret\":\"$(echo -n $COOKIE_SECRET | base64)\"}}}"
kubectl rollout restart deploy/oauth2-proxy -n temporal
oauth2-proxy crashes with "connection refused"
Error in logs:
upstream connect error or disconnect/reset before headers
Likely cause: temporal-web service not accessible.
Check:
kubectl get svc -n temporal temporal-web
kubectl exec -n temporal deploy/oauth2-proxy -- curl http://temporal-web:8080
File Structure
k8s/temporal/
├── oauth2-proxy.yaml # oauth2-proxy Deployment + Service + SA
├── temporal-ingress-oauth2.yaml # Ingress routing to oauth2-proxy
├── oauth2-proxy-values.yaml # Helm values (reference only)
└── temporal-values.yaml # Modified: ingress.enabled=false
Next: Add to Helmfile
If integrating with helmfile.yaml.gotmpl:
releases:
- name: temporal
# ... existing config ...
hooks:
postSync:
- events: ["success"]
showlogs: true
command: "sh"
args:
- -c
- |
kubectl apply -f k8s/temporal/oauth2-proxy.yaml
kubectl apply -f k8s/temporal/temporal-ingress-oauth2.yaml
Or add separate releases:
- name: oauth2-proxy-temporal
namespace: temporal
chart: oauth2-proxy/oauth2-proxy
version: "6.x.x"
values:
- k8s/temporal/oauth2-proxy-values.yaml
set:
- name: config.clientSecret
value: "{{ (env "TEMPORAL_OIDC_CLIENT_SECRET") }}"
- name: config.cookieSecret
value: "{{ (env "TEMPORAL_OIDC_COOKIE_SECRET") }}"
Then add to .env:
TEMPORAL_OIDC_CLIENT_SECRET=<from Authentik>
TEMPORAL_OIDC_COOKIE_SECRET=$(openssl rand -base64 32)