Dosu LogoDosu Logo
Ask
Join our Discord
homepagePublic
homepage
Documentshomepage
OIDC Authentication
OIDC Authentication
Type
Topic
Status
Published
Created
Sep 19, 2026
Updated
Sep 23, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

OIDC Authentication#

Homepage (v2.0+) supports OpenID Connect (OIDC) as an authentication gate, implemented via NextAuth.js. When HOMEPAGE_OIDC_ISSUER, HOMEPAGE_OIDC_CLIENT_ID, and HOMEPAGE_OIDC_CLIENT_SECRET are all provided, OIDC mode activates and overrides password-based login . All app pages and /api routes — except /api/healthcheck, /api/config/custom.css, and the NextAuth/auth paths — require a valid session when auth is enabled .

Authorization is fully delegated to the identity provider. Homepage grants access to any identity the provider authorizes for this client; configure group membership, access policies, or client assignments at the provider level, not in Homepage .

The primary implementation files are:

FileRole
src/pages/api/auth/[...nextauth].jsNextAuth handler — provider registration, session strategy (jwt), startup validation
src/utils/env.jsapplyNextAuthEnv() / isAuthEnabled() — maps HOMEPAGE_* vars to NextAuth internals
src/middleware.jsRoute protection — enforces JWT session on all non-public paths

Configuration#

All three HOMEPAGE_OIDC_* variables must be set together — providing any partial subset throws a startup error .

VariableRequiredNotes
HOMEPAGE_AUTH_ENABLEDYesMust be true
HOMEPAGE_AUTH_SECRETYesMin 32 chars; mapped to NEXTAUTH_SECRET. Generate with openssl rand -base64 32
HOMEPAGE_EXTERNAL_URLYesAbsolute HTTP(S) URL — scheme + host + port — mapped to NEXTAUTH_URL
HOMEPAGE_OIDC_ISSUERYesProvider base URL; trailing slashes stripped automatically
HOMEPAGE_OIDC_CLIENT_IDYesClient ID registered at the provider
HOMEPAGE_OIDC_CLIENT_SECRETYesClient secret
HOMEPAGE_OIDC_NAMENoSign-in button label (default: Homepage OIDC)
HOMEPAGE_OIDC_SCOPENoOAuth scopes (default: openid email profile)
HOMEPAGE_OIDC_AUTO_LOGINNotrue skips the sign-in page and redirects straight to the provider

Set your OIDC provider's redirect / callback URI to:

https://<your-homepage-url>/api/auth/callback/homepage-oidc

Homepage registers the provider with idToken: true and checks: ["pkce", "state", "nonce"] . Secure cookies are enabled automatically when HOMEPAGE_EXTERNAL_URL uses https: .

Tip: With HOMEPAGE_OIDC_AUTO_LOGIN=true, bypass the automatic redirect for troubleshooting by visiting /auth/signin?autologin=0 .


Supplying Secrets Securely#

Avoid embedding raw secrets in compose files. Use Docker Swarm secrets or env_file files — but be aware that Docker does not strip literal quote characters, so HOMEPAGE_OIDC_CLIENT_SECRET="abc" will pass "abc" (with quotes) as the secret value .

For variable substitution inside Homepage config files, see HOMEPAGE_VAR_* and HOMEPAGE_FILE_* .


Troubleshooting#

Verbose error logs#

The latest Docker image tag may log only a generic OAUTH_CALLBACK_ERROR without the underlying cause. Switch to the :dev tag to get verbose error messages including the specific rejection reason .

JWT algorithm mismatch (unexpected JWT alg received, expected RS256, got: HS256)#

Homepage requires RS256-signed ID tokens (idToken: true) . Some providers — notably Authentik — default to HS256.

Fix (Authentik): Go to System → Certificates, generate a new RSA certificate-key pair, then edit the Homepage provider, set Signing Key to that certificate, and save .

Client authentication failure (invalid_client)#

The authorization code exchange succeeds (provider redirects back) but the backend token-endpoint call is rejected. Common causes :

  • Wrong client type — the provider client must be Confidential, not Public.
  • Secret mismatch — copy the secret from the provider's detail page (not the list view, which may truncate). Avoid quoting the value in env_file.
  • Wrong issuer scope — in Authentik, credentials are scoped per provider; verify HOMEPAGE_OIDC_ISSUER matches the exact provider slug holding the registered client.

Check the provider's own token-endpoint logs for the authoritative rejection reason.

TLS / certificate trust (SIGNIN_OAUTH_ERROR)#

Node.js uses its own TLS trust store, not the container's system /etc/ssl/certs/. If your OIDC issuer uses a private or self-signed CA, Homepage cannot fetch the discovery document .

Diagnose by running inside the container:

docker exec homepage node -e \
  'const i=process.env.HOMEPAGE_OIDC_ISSUER.replace(/\/+$/,""); \
   fetch(i+"/.well-known/openid-configuration").then(r=>console.log(r.status,r.statusText)).catch(console.error)'

Fix — mount your root CA and set NODE_EXTRA_CA_CERTS:

volumes:
  - ./rootCA.crt:/usr/local/share/ca-certificates/rootCA.crt:ro
environment:
  NODE_EXTRA_CA_CERTS: /usr/local/share/ca-certificates/rootCA.crt

Mounting /etc/ssl/certs/ from the host is not sufficient; Node.js ignores that path .

Cookie / state validation failures#

State, PKCE, and nonce are stored in cookies scoped to HOMEPAGE_EXTERNAL_URL. If the URL in the browser doesn't exactly match (scheme, hostname, port), cookies are absent on callback and the flow silently fails. Verify HOMEPAGE_EXTERNAL_URL equals the URL shown in the browser's address bar exactly .


Further Reading#

  • Homepage authentication docs — official configuration reference
  • Discussion: Unable to get Authentik OIDC working — community troubleshooting thread
  • Discussion: OIDC login OAuthCallback errors — algorithm mismatch and TLS walkthrough
Documents
Background Image Rendering
settings
CrowdSec Widget
Docker Socket Permissions on Synology
Dockerode Integration
Ghostfolio Widget Currency Handling
Jellyfin Widget API Compatibility
jellyfin
OIDC Authentication
Quick Launch Click Handling
Widget Proxy Request Handling
customapi
YAML Configuration Loading
CONTRIBUTING
README
adguard-home
apcups
api
arcane
argocd
atsumeru
audiobookshelf
authentik
autobrr
azuredevops
backrest
bazarr
beszel
booklore
bookmarks
bookorbit
caddy
calendar
calibre-web
changedetectionio
channelsdvrserver
checkmk
cloudflared
coin-market-cap
component
coverage
crowdsec
custom-css-js
customapi
datetime
deluge
develancacheui
diskstation
dispatcharr
docker
docker
dockhand
downloadstation
duplicati
emby
esphome
evcc
feed
filebrowser
fileflows
firefly
flood
freshrss
frigate
fritzbox
gamedig
gatus
getting-started
ghostfolio
gitea
gitlab
glances
glances
gluetun
gotify
grafana
greeting
hdhomerun
headscale
healthchecks
homeassistant
homebox
homebridge
homepage-move
iframe
immich
index
index
index
index
index
index
index
index
index
info-widgets
jackett
jdownloader
jellystat
k8s
karakeep
kavita
komga
komodo
kopia
kubernetes
kubernetes
lidarr
linkwarden
logo
longhorn
lubelogger
mailcow
maintainerr
mastodon
mcp
mealie
medusa
metadata
mikrotik
minecraft
miniflux
mjpeg
moonraker
mylar
myspeed
navidrome
netalertx
netdata
nextcloud
nextdns
nginx-proxy-manager
ntfy
nzbget
octoprint
omada
ombi
opendtu
openmediavault
openmeteo
openweathermap
openwrt
opnsense
pangolin
paperlessngx
peanut
pfsense
photoprism
pihole
plantit
plex
plex-tautulli
portainer
prometheus
prometheusmetric
prowlarr
proxies
proxmox
proxmox
proxmoxbackupserver
pterodactyl
pulse
pyload
qbittorrent
qnap
qui
radarr
readarr
resources
romm
rutorrent
sabnzbd
scrutiny
search
seerr
services
slskd
sonarr
source
sparkyfitness
speedtest-tracker
sponsors
spoolman
sportarr
stash
stocks
stocks
suwayomi
swagdashboard
syncthing
syncthing-relay-server
tailscale
tandoor
tdarr
technitium
tracearr
traefik
translations
translations
transmission
trilium
truenas
tubearchivist
tutorial
unifi-controller
unifi-drive
unifi_controller
unmanic
unraid
unraid
uptime-kuma
uptimerobot
urbackup
vikunja
wallos
watchtower
wgeasy
whatsupdocker
xteve
yourspotify
zabbix