Files
homelab/k8s/temporal/TEMPORAL_OAUTH2_SETUP.md
T

221 lines
5.3 KiB
Markdown
Raw Normal View History

# 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:
```bash
kubectl get secret -n temporal temporal-oidc
kubectl describe secret -n temporal temporal-oidc
```
### If missing, create it:
```bash
# 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
```bash
kubectl apply -f k8s/temporal/oauth2-proxy.yaml
```
Verify:
```bash
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
```bash
kubectl apply -f k8s/temporal/temporal-ingress-oauth2.yaml
```
Verify:
```bash
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
1. **Open Temporal UI (unauthenticated):**
```bash
open https://temporal.riotpiao.homelab.com
```
Expected: Redirects to Authentik login page
2. **Login with Authentik credentials**
- Username/email
- Password
- Should redirect back to `temporal.riotpiao.homelab.com` and display UI
3. **Verify auth:**
```bash
# Check for oauth2_proxy cookie
curl -v https://temporal.riotpiao.homelab.com 2>&1 | grep -i cookie
```
4. **Check oauth2-proxy logs:**
```bash
kubectl logs -n temporal deploy/oauth2-proxy -f
```
Look 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:
```bash
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:
```bash
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:
```bash
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:
```yaml
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:
```yaml
- 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`:
```bash
TEMPORAL_OIDC_CLIENT_SECRET=<from Authentik>
TEMPORAL_OIDC_COOKIE_SECRET=$(openssl rand -base64 32)
```