arr-stack SSO Implementation Guide¶
This guide documents how to add Authentik forward auth to arr-stack services.
General Pattern: See Authentik Forward Auth Pattern for the reusable template.
Overview¶
arr-stack apps (Sonarr, Radarr, Jellyseerr, etc.) don't support native LDAP/OIDC. We use Authentik forward auth via K8s Ingress to control access.
Architecture:
User → jellyseerr.bogocat.com → K8s Ingress (10.89.97.220)
│
▼
┌─────────────────────┐
│ nginx auth_request │
│ → Authentik server │
└─────────────────────┘
│
┌─────────────┴─────────────┐
│ │
(not authenticated) (authenticated)
│ │
▼ ▼
Redirect to Authentik Proxy to arr-stack
login via /outpost.go... VM 100 (10.89.97.50)
Prerequisites¶
- Authentik deployed in K8s (
authentiknamespace) - Embedded outpost configured (type: proxy)
- DNS entries pointing to K8s ingress (10.89.97.220)
- arr-stack running on VM 100 (10.89.97.50)
Access Groups¶
| Group | Services | Members |
|---|---|---|
arr-users |
Jellyseerr, Overseerr | jake, akadmin, guest |
arr-admins |
Sonarr, Radarr, Lidarr, Prowlarr, Bazarr, SABnzbd, Deluge | jake, akadmin |
Groups are already created in Authentik.
Services Reference¶
| Service | Port | DNS | Group | Status |
|---|---|---|---|---|
| Jellyseerr | 5056 | jellyseerr.bogocat.com | arr-users | ✅ Done |
| Overseerr | 5055 | overseerr.bogocat.com | arr-users | ✅ Done |
| Sonarr | 8989 | sonarr.bogocat.com | arr-admins | ✅ Done |
| Radarr | 7878 | radarr.bogocat.com | arr-admins | ✅ Done |
| Lidarr | 8686 | lidarr.bogocat.com | arr-admins | ✅ Done |
| Prowlarr | 9696 | prowlarr.bogocat.com | arr-admins | ✅ Done |
| Bazarr | 6767 | bazarr.bogocat.com | arr-admins | ✅ Done |
| SABnzbd | 8080 | sabnzbd.bogocat.com | arr-admins | ✅ Done |
| Deluge | 8112 | deluge.bogocat.com | arr-admins | ✅ Done |
Adding a New App (Step-by-Step)¶
Step 1: Create Proxy Provider in Authentik¶
- Go to http://auth.bogocat.com → Login as akadmin
- Navigate to Providers → Create → Proxy Provider
- Configure:
| Field | Value |
|---|---|
| Name | {app-name}-proxy (e.g., sonarr-proxy) |
| Authorization flow | default-provider-authorization-implicit-consent |
| Forward auth mode | Forward auth (single application) |
| External host | http://{app-name}.bogocat.com (e.g., http://sonarr.bogocat.com) |
Step 2: Create Application¶
- Navigate to Applications → Create
- Configure:
| Field | Value |
|---|---|
| Name | {App Name} (e.g., Sonarr) |
| Slug | {app-name} (e.g., sonarr) |
| Provider | Select {app-name}-proxy |
- Click Create
- Click on the new application → Policy / Group / User Bindings
- Create Binding → Group → Select appropriate group (
arr-usersorarr-admins)
Step 3: Assign to Embedded Outpost¶
- Navigate to Applications → Outposts
- Click authentik Embedded Outpost → Edit
- In Applications, add the new application
- Click Update
Step 4: Create K8s Manifest¶
Copy and modify the template below, save as /root/tower-fleet/manifests/arr-stack/{app-name}.yaml:
# {App Name} Forward Auth Configuration
---
# ConfigMap for auth request headers
apiVersion: v1
kind: ConfigMap
metadata:
name: {app-name}-auth-headers
namespace: arr-stack
data:
X-Forwarded-Host: "{app-name}.bogocat.com"
X-Forwarded-Proto: "http"
---
# Headless service + Endpoints for external IP routing
apiVersion: v1
kind: Service
metadata:
name: {app-name}-external
namespace: arr-stack
labels:
app.kubernetes.io/name: {app-name}
app.kubernetes.io/managed-by: tower-fleet
spec:
type: ClusterIP
clusterIP: None
ports:
- name: http
port: {PORT}
targetPort: {PORT}
---
apiVersion: v1
kind: Endpoints
metadata:
name: {app-name}-external
namespace: arr-stack
labels:
app.kubernetes.io/name: {app-name}
app.kubernetes.io/managed-by: tower-fleet
subsets:
- addresses:
- ip: 10.89.97.50
ports:
- name: http
port: {PORT}
---
# Service to reach Authentik server from this namespace
apiVersion: v1
kind: Service
metadata:
name: {app-name}-authentik
namespace: arr-stack
spec:
type: ExternalName
externalName: authentik-server.authentik.svc.cluster.local
---
# Ingress for Authentik outpost paths (login flow)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {app-name}-outpost
namespace: arr-stack
labels:
app.kubernetes.io/name: {app-name}
app.kubernetes.io/managed-by: tower-fleet
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/upstream-vhost: "authentik-server.authentik.svc.cluster.local"
spec:
ingressClassName: nginx
rules:
- host: {app-name}.bogocat.com
http:
paths:
- path: /outpost.goauthentik.io/
pathType: Prefix
backend:
service:
name: {app-name}-authentik
port:
number: 80
---
# Main app ingress with forward auth
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {app-name}
namespace: arr-stack
labels:
app.kubernetes.io/name: {app-name}
app.kubernetes.io/managed-by: tower-fleet
annotations:
nginx.ingress.kubernetes.io/auth-url: "http://authentik-server.authentik.svc.cluster.local/outpost.goauthentik.io/auth/nginx"
nginx.ingress.kubernetes.io/auth-signin: "http://{app-name}.bogocat.com/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-uid"
nginx.ingress.kubernetes.io/auth-proxy-set-headers: "arr-stack/{app-name}-auth-headers"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
rules:
- host: {app-name}.bogocat.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {app-name}-external
port:
number: {PORT}
Replace:
- {app-name} → lowercase app name (e.g., sonarr)
- {App Name} → display name (e.g., Sonarr)
- {PORT} → service port (see Services Reference table)
Step 5: Apply K8s Manifest¶
Step 6: Add DNS Entry¶
In OPNsense:
1. Services → Unbound DNS → Host Overrides
2. Add: {app-name}.bogocat.com → 10.89.97.220
3. Apply changes
Step 7: Test¶
- Open incognito browser
- Go to
http://{app-name}.bogocat.com - Should redirect to Authentik login
- Login with a user in the correct group
- Should redirect back to the app
Key Learnings / Gotchas¶
ExternalName services don't work with nginx-ingress for IPs¶
Use headless Service + Endpoints instead:
Why this pattern exists: arr-stack apps run on VM 100 (10.89.97.50), not in K8s. Since Ingress backends require a Service name (not an IP), we create a headless Service with manually-defined Endpoints pointing to the VM. This is a workaround for routing K8s Ingress traffic to external IPs.
When arr-stack migrates to K8s: This pattern will be replaced with standard ClusterIP Services that auto-discover pods via label selectors. See arr-stack K8s Migration for details (currently deferred).
Forward auth needs X-Forwarded-Host header¶
The embedded outpost matches requests by host. Pass via ConfigMap:
Outpost paths must be routed via same hostname¶
The /outpost.goauthentik.io/start and /outpost.goauthentik.io/callback paths need their own ingress under the app's hostname, not auth.bogocat.com.
configuration-snippet is disabled¶
The nginx-ingress controller has snippets disabled. Use auth-proxy-set-headers with ConfigMap instead.
Forward auth ≠ SSO¶
Forward auth controls WHO can access the app. Users still need to log into the app itself separately. This is expected behavior.
Troubleshooting¶
404 on /outpost.goauthentik.io/auth/nginx¶
- Check application is assigned to embedded outpost
- Restart Authentik server:
kubectl rollout restart deployment -n authentik authentik-server
503 Service Unavailable¶
- Check Endpoints exist:
kubectl get endpoints -n arr-stack - Verify VM is reachable:
curl http://10.89.97.50:{PORT}
500 Internal Server Error¶
- Check ingress controller logs:
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller --tail=50
Redirect loop¶
- Clear browser cookies
- Check auth-signin URL matches the app hostname
Files Reference¶
| File | Purpose |
|---|---|
/root/tower-fleet/manifests/arr-stack/namespace.yaml |
Namespace definition |
/root/tower-fleet/manifests/arr-stack/jellyseerr.yaml |
Jellyseerr forward auth config |
/root/tower-fleet/manifests/arr-stack/overseerr.yaml |
Overseerr forward auth config |
/root/tower-fleet/manifests/arr-stack/sonarr.yaml |
Sonarr forward auth config |
/root/tower-fleet/manifests/arr-stack/radarr.yaml |
Radarr forward auth config |
/root/tower-fleet/manifests/arr-stack/lidarr.yaml |
Lidarr forward auth config |
/root/tower-fleet/manifests/arr-stack/prowlarr.yaml |
Prowlarr forward auth config |
/root/tower-fleet/manifests/arr-stack/bazarr.yaml |
Bazarr forward auth config |
/root/tower-fleet/manifests/arr-stack/sabnzbd.yaml |
SABnzbd forward auth config |
/root/tower-fleet/manifests/arr-stack/deluge.yaml |
Deluge forward auth config |
/root/tower-fleet/manifests/arr-stack/README.md |
Quick reference |