# 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.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.com      ...       80, 443   10s
```

### Step 3: Test Access

1. **Open Temporal UI (unauthenticated):**
   ```bash
   open https://temporal.riotpiao.com
   ```
   
   Expected: Redirects to Authentik login page

2. **Login with Authentik credentials**
   - Username/email
   - Password
   - Should redirect back to `temporal.riotpiao.com` and display UI

3. **Verify auth:**
   ```bash
   # Check for oauth2_proxy cookie
   curl -v https://temporal.riotpiao.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.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)
```
