k8s/messaging: add kafka kmsvc and temporal workflows
- Kafka 3-broker cluster (RF=3, min-ISR=2) - kmsvc SQS-like API on Kafka - Redis dedup (standalone, can extend to HA) - Temporal workflow orchestration (Cassandra backend)
This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# 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)
|
||||
```
|
||||
Reference in New Issue
Block a user