Two layers. Both are required.
Every request to these endpoints must include the configured secret header:
/sso/RemoteAuth/Login/sso/RemoteAuth/QuickConnect/sso/RemoteAuth/QuickConnect/Authorize
Wrong or missing secret → 401. Blank Secret Header Value in config → 503 (plugin refuses all requests).
Comparison uses constant time (CryptographicOperations.FixedTimeEquals). Generate with openssl rand -hex 32 (or equivalent).
The secret alone is not enough. Anyone who can reach the endpoint and guess the secret can authenticate as any user.
Only your reverse proxy may reach the SSO endpoints above.
Put Jellyfin on an internal network. Only the proxy container shares that network. Do not publish port 8096 on the host.
networks:
proxy: # proxy → Jellyfin
internal: false
internal: # Jellyfin-only services
internal: true
services:
proxy:
networks: [proxy]
jellyfin:
networks: [proxy, internal]
# Do NOT publish port 8096 directlyIsolation for the Jellyfin pod (port 8096 is not path-scoped; the proxy still must inject the secret).
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: jellyfin-remoteauth-ingress
namespace: jellyfin
spec:
podSelector:
matchLabels:
app: jellyfin
policyTypes: [Ingress]
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: traefik
podSelector:
matchLabels:
app: traefik
ports:
- port: 8096For Traefik Ingress + Middleware CRDs (headers and secret injection), see proxy.md.