Single Sign-On for the Homelab with Keycloak
Putting every self-hosted service behind one login with the same identity provider I use at work. OIDC for the apps that support it, oauth2-proxy for the ones that don't, and the trade-offs of each.
Single Sign-On for the Homelab with Keycloak
The problem
Self-hosting is fun until you have eighteen browser tabs each demanding a different password. Some apps have great auth (Grafana). Some have okay auth (Vaultwarden). Some have terrible auth or none at all (every static dashboard ever).
The goal: one credential, one MFA prompt per session, regardless of which service.
Why Keycloak
The honest answer is deliberate overlap with my day job. Keycloak is what we run at work, and the homelab is a low-stakes environment to deepen that fluency — realm configuration, client scopes, identity brokering, mappers, the lot. Every time I hit a weird edge in the homelab Keycloak, that's a problem I'm now equipped to debug in production.
There are gentler-on-the-eyes options (Authentik notably) — but for me the learning leverage of using the same tool across both contexts is worth more than the friction of Keycloak's more enterprise-grained UI.
Two integration patterns
OIDC native: when the app supports it. Grafana, Nextcloud, Portainer all do. Configure a client in Keycloak, paste the client ID/secret into the app, set the right scopes, done. This is the path of least surprise.
Forward-auth via nginx + oauth2-proxy: for apps with no SSO support. Keycloak doesn't ship a forward-auth proxy of its own (unlike Authentik's outpost), so the typical pattern is to put oauth2-proxy in front of the app. nginx delegates auth decisions to oauth2-proxy via the auth_request directive, oauth2-proxy talks OIDC to Keycloak, and the proxied app sees authenticated requests with headers like X-Forwarded-User. Some apps can be configured to trust these headers; others can't, and you're stuck putting the app behind a "gate" without it knowing — but the gate is still real.
Cost paid
Keycloak itself is another service to maintain — and it's a heavier service than Authentik, Dex, or the lighter alternatives. The JVM footprint is real. The day it's down, you can't log in to anything. I run it on its own VM (not on the Kubernetes cluster) precisely so that cluster issues don't lock me out of the cluster's auth.
The other cost is configuration drift. Keycloak's realm settings are powerful enough that I've broken things by clicking around in the admin console without writing it down. Lesson learned: realm exports go into the Git repo, the same way the GitOps repo holds everything else.
What I'd skip
Don't put your password manager behind SSO. If something goes wrong with SSO, you need to be able to retrieve credentials. Circular dependency.