Expand service list; add OIDC section and Case 2b

- snippets.caddyfile: rename Case 2 → 2a (proxy headers); add Case 2b
  (OIDC) sub-section explaining the token exchange flow, with blocks for
  Audiobookshelf, Jellyfin, Immich, Mealie, Portainer
- snippets.caddyfile: add Case 1 blocks for Prometheus, Alertmanager,
  Gatus, WatchYourLAN, NUT web UI
- snippets.caddyfile: add Case 3 blocks for qBittorrent, Plex (with
  client-bypass caveat), Emby, Gotify, ntfy, wg-easy (with WireGuard
  UDP caveat), Umami, phpIPAM, Checkmk, Snipe-IT, Zammad, Lubelog,
  UniFi, MeshCentral
- README: add OIDC plain-language explanation (what it is, how it differs
  from proxy-header auth, what setup it requires)
- README: expand service table to 30+ entries grouped by case; add ⚠
  caveats for Plex/Emby (clients bypass Caddy)
- README: fix Case 1 header (remove phpIPAM, which has its own auth →
  Case 3); fix stale `caddy/Caddyfile` reference → snippets.caddyfile

https://claude.ai/code/session_012eTokAaGiZo7aGt1T2W9BC
This commit is contained in:
Claude
2026-04-26 15:20:06 +00:00
parent 6cf6a2aeb8
commit 6252271816
2 changed files with 323 additions and 46 deletions
+246 -24
View File
@@ -51,8 +51,9 @@ auth.{env.DOMAIN} {
# =============================================================================
# CASE 1 -- App has NO built-in auth. Authelia is the only gate.
#
# Examples: Homer, Heimdall, Dozzle, phpIPAM, any internal tool with no
# login page. Use two_factor in authelia/configuration.yml for these.
# Examples: Homer, Heimdall, Dozzle, Prometheus, Alertmanager, Gatus,
# WatchYourLAN, NUT web UI. Use two_factor in
# authelia/configuration.yml for any of these.
# =============================================================================
# Homer / Heimdall dashboard (no auth whatsoever)
@@ -69,7 +70,49 @@ dozzle.{env.DOMAIN} {
reverse_proxy 192.168.x.x:8888 # CHANGE IP:PORT
}
# Pi doorbell PTT page (Flask server, no auth)
# --- Prometheus ---
# No authentication built in. Always gate it -- metrics expose internal details.
# prom.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:9090 # CHANGE IP
# }
# --- Alertmanager ---
# No authentication built in.
# alerts.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:9093 # CHANGE IP
# }
# --- Gatus ---
# Status / uptime page. Has optional built-in OIDC but simpler to gate here.
# status.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8080 # CHANGE IP
# }
# --- WatchYourLAN ---
# Network ARP scanner. No built-in auth.
# lan.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8840 # CHANGE IP
# }
# --- NUT (Network UPS Tools) web UI ---
# The NUT daemon (upsd) has no web UI itself. Common frontends -- NUT-Monitor,
# upsd-web, various Docker images -- have minimal or no auth. Gate whichever
# you run here. Port varies by image.
# ups.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:PORT # CHANGE IP:PORT
# }
# --- Pi doorbell PTT page (Flask server, no auth) ---
# Uncomment when the Pi is deployed.
# doorbell.{env.DOMAIN} {
# import accesslog
@@ -85,8 +128,8 @@ dozzle.{env.DOMAIN} {
# =============================================================================
# CASE 2 -- App supports trusted-header proxy auth. Authelia replaces its
# own login form. Single login, app reads Remote-User for roles.
# CASE 2a -- App supports trusted-header proxy auth. Authelia replaces its
# own login form. Single login, app reads Remote-User for roles.
#
# Requires per-app config changes -- see notes in each block.
# =============================================================================
@@ -167,20 +210,87 @@ miniflux.{env.DOMAIN} {
}
# --- BookStack ---
# See BookStack docs for HTTP header auth (requires the SAML2 or HTTP auth method).
# In .env:
# AUTH_METHOD=http
# HTTP_AUTH_HEADER=Remote-User
# HTTP_AUTH_AUTO_INITIATE=true
# bookstack.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:80 # CHANGE IP
# }
# =============================================================================
# CASE 2b -- App supports OIDC. Authelia acts as the OIDC provider.
#
# What is OIDC? OpenID Connect is an identity protocol on top of OAuth 2.0.
# Authelia becomes the "identity provider" (IdP). Apps redirect users to
# auth.DOMAIN, Authelia authenticates them and issues a signed token (JWT),
# then redirects back. The app trusts the token instead of checking a password.
#
# The Caddy config is identical to case 2a: `import authelia` gates the request.
# The difference is all on the app side -- it does a token exchange with
# Authelia's OIDC endpoint rather than reading a Remote-User header.
#
# SETUP REQUIRED in authelia/configuration.yml:
# Add an identity_providers.oidc block with a client entry for each app.
# Each app gets its own client_id and client_secret.
# See: https://www.authelia.com/configuration/identity-providers/openid-connect/
#
# Result: users never set a password in the app itself. After OIDC is working,
# disable all local accounts in the app -- Authelia is the only credential.
# =============================================================================
# --- Audiobookshelf ---
# Native OIDC support. In Audiobookshelf Settings > Authentication:
# Enable OpenID Connect SSO
# Issuer URL: https://auth.DOMAIN
# Client ID / Secret: from identity_providers.oidc in configuration.yml
# Auto Register: on (creates user on first OIDC login)
# books.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:13378 # CHANGE IP
# }
# --- Jellyfin ---
# Requires the community SSO plugin (Jellyfin.Plugin.SSO).
# Install from the Plugin Catalogue, then configure OIDC pointing at Authelia.
# jellyfin.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8096 # CHANGE IP
# }
# --- Immich ---
# Proxy auth headers not supported; use Authelia as OIDC provider instead.
# Configure Authelia's identity_providers.oidc block and point Immich at it.
# No proxy-header auth; OIDC is the only Authelia path.
# In Immich Admin > Authentication Settings > OAuth:
# Issuer URL: https://auth.DOMAIN
# Client ID / Secret: from configuration.yml
# Auto register: on
# photos.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:2283 # CHANGE IP
# reverse_proxy 192.168.x.x:2283 # CHANGE IP
# }
# --- Mealie ---
# OIDC supported. Set in Mealie's admin OIDC settings.
# Alternatively, skip OIDC and use case 3 as a simpler gate.
# mealie.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:9000 # CHANGE IP
# }
# --- Portainer ---
# Has OIDC for full SSO -- configure under Settings > Authentication.
# Or use case 3 (below) as a simpler gate without OIDC config.
# portainer.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:9000 # CHANGE IP (OIDC version)
# }
@@ -188,9 +298,8 @@ miniflux.{env.DOMAIN} {
# CASE 3 -- App keeps its own login. Authelia adds a 2FA gate in front.
#
# The user passes Authelia 2FA, then the app's own login appears.
# Use for apps that don't support proxy auth headers but you still want
# 2FA before they're even reachable. This is the only way to get TOTP
# in front of apps that don't natively support it.
# Use for apps that don't support proxy auth headers or OIDC, but you still
# want 2FA before they're even reachable.
# =============================================================================
# --- Uptime Kuma ---
@@ -201,25 +310,15 @@ uptime.{env.DOMAIN} {
reverse_proxy 192.168.x.x:3001 # CHANGE IP
}
# --- Portainer ---
# No proxy auth header support (use OIDC for full SSO instead).
# --- Portainer (simple gate, no OIDC) ---
portainer.{env.DOMAIN} {
import accesslog
import authelia
reverse_proxy 192.168.x.x:9000 # CHANGE IP
}
# --- Mealie ---
# Has OIDC support -- can do full case 2 with Authelia as OIDC provider.
# For simpler case-3 gate:
# mealie.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:9000 # CHANGE IP
# }
# --- Home Assistant ---
# Can also do case 2 via the trusted_networks auth provider + header forwarding.
# Can also do case 2a via the trusted_networks auth provider + header forwarding.
# homeassistant.{env.DOMAIN} {
# import accesslog
# import authelia
@@ -236,6 +335,129 @@ portainer.{env.DOMAIN} {
# reverse_proxy 192.168.x.x:80 # CHANGE IP
# }
# --- qBittorrent ---
# Web UI has its own auth. No proxy headers.
# torrent.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8080 # CHANGE IP:PORT
# }
# --- Plex ---
# IMPORTANT: Plex is tightly coupled to plex.tv cloud auth -- Authelia cannot
# replace it. This gate applies to the web UI only. Plex clients (mobile, TV,
# desktop apps) communicate directly with the server port and bypass Caddy
# entirely, so the gate does not protect those paths. Tailscale or VPN is
# the better approach for Plex remote access.
# plex.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:32400 # CHANGE IP
# }
# --- Emby ---
# Same caveat as Plex: Emby clients bypass Caddy. Web UI gate only.
# emby.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8096 # CHANGE IP
# }
# --- Gotify ---
# Notification server. Own auth, no proxy headers.
# gotify.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8080 # CHANGE IP
# }
# --- ntfy ---
# Notification server. Token-based auth, no proxy headers.
# ntfy.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:80 # CHANGE IP
# }
# --- wg-easy ---
# WireGuard web UI. Own password, no proxy headers.
# NOTE: WireGuard clients connect directly to UDP 51820, not through Caddy.
# This gate only protects the web management UI.
# wg.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:51821 # CHANGE IP
# }
# --- Umami ---
# Web analytics. Own auth, no proxy headers.
# analytics.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:3000 # CHANGE IP
# }
# --- phpIPAM ---
# IP address management. Own auth, no proxy headers.
# ipam.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:80 # CHANGE IP
# }
# --- Checkmk ---
# Monitoring. Own auth. No proxy headers in the free (Raw) edition.
# checkmk.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:5000 # CHANGE IP
# }
# --- Snipe-IT ---
# Asset management. Own auth, no proxy headers.
# assets.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:80 # CHANGE IP
# }
# --- Zammad ---
# Help desk / ticketing. Own auth, no proxy headers.
# tickets.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:3000 # CHANGE IP
# }
# --- Lubelog ---
# Vehicle maintenance log. Own auth, no proxy headers.
# cars.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8080 # CHANGE IP
# }
# --- UniFi Network Application ---
# Network controller. Own auth, no proxy headers (LDAP/RADIUS in enterprise).
# Serves HTTPS on 8443; skip TLS verify for the upstream.
# unifi.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:8443 { # CHANGE IP
# transport http { tls_insecure_skip_verify }
# }
# }
# --- MeshCentral ---
# Remote management server. Own auth; has OIDC in paid/enterprise builds.
# meshcentral.{env.DOMAIN} {
# import accesslog
# import authelia
# reverse_proxy 192.168.x.x:443 { # CHANGE IP
# transport http { tls_insecure_skip_verify }
# }
# }
# =============================================================================
# CASE 4 -- App handles its own auth. Authelia not involved.