$ sudo reboot_

// Security

Ten apps, ten passwords, zero patience: putting SSO in front of the homelab

by Jon · · 2 min read

A brass padlock with its keys
Photo: Trougnouf, CC BY 4.0, via Wikimedia Commons

Every self-hosted app arrives with its own little user database, and they multiply like rabbits. By app number ten you've got ten passwords, ten places to remove someone, and ten login pages facing the internet, each written by a different team with a different idea of what "secure" means. A self-hosted identity provider (Authentik, in my case) collapses all of that into one account, one place for two-factor authentication, and groups that decide who sees what.

Two ways to put a lock on the door

OpenID Connect, when the app plays along

Most modern apps can act as an OIDC client. You create a provider and an application in the identity provider, paste the client ID (plus a secret, for server-side apps) into the app, and a shiny Sign in with… button appears. Users get created on first login, and plenty of apps can map an identity-provider group straight to an admin role.

Forward authentication, when it won't

Some apps have no login at all, or one you wouldn't trust with a grocery list. For those, the reverse proxy asks the identity provider before letting a request through, so nobody even reaches the app without signing in first. In my proxy this boiled down to a single flag per route. Protecting another app is now a one-word change, which is exactly the amount of effort security should take.

The parts nobody warned me about

  • Public vs. confidential clients. Desktop and mobile apps can't keep a secret, so they need a public client with PKCE, plus every redirect URI they might use, including custom URL schemes and the odd random localhost port.
  • Claims matter. A lot. One app refused every single login until the email_verified claim said true. The default scope mapping sent false. A custom mapping later, everyone was in.
  • Hide and seek. One app hid its SSO button until a second, completely unrelated setting was filled in. Another rewrote its own config file from memory on restart and quietly threw my changes away. Always re-check after a restart.
  • Keep a local admin. Every app still keeps one password account that doesn't depend on the identity provider, for the day the identity provider is the thing that's down.

Worth it?

Absolutely. Adding someone is now one account and one group membership, and cutting off access is a single switch. The login page the internet sees belongs to the identity provider, which gets security fixes far more often than most small apps ever will.