How YunoHost's Built-In SSO Actually Works: LDAP, SSOWAT, and One Cookie to Rule Your Apps
YunoHost's SSO combines a localhost LDAP directory with the SSOWAT proxy gatekeeper so one portal login unlocks every protected app. Here's how the pieces fit, how to verify them, and where the limits are.
02 Mar 2026, 16:00 UTC

If you self-host half a dozen web apps, you know the login fatigue: Nextcloud has its accounts, your RSS reader has another set, the wiki a third. YunoHost's answer to this is a single sign-on system that ships enabled by default, and it's worth understanding how it actually works before you rely on it — or try to integrate something outside of it.
The short version: YunoHost pairs an internal LDAP directory with a reverse-proxy gatekeeper called SSOWAT. Users log in once at the YunoHost portal, and every protected app behind the proxy trusts that session. No per-app passwords, no extra accounts to provision.
Two components doing one job
The first piece is a read-only LDAP directory. YunoHost stores user accounts, groups, and SSHA-hashed passwords under cn=yunohost,cn=users,dc=yunohost,dc=org, served by an LDAP daemon bound to localhost:389. Every user you create in the admin panel becomes an entry here.
The second piece is SSOWAT, a Lua-based authentication layer that runs inside the nginx reverse proxy. It intercepts every HTTP request to an installed app and asks one question: does this request carry a valid session cookie? If yes, the request passes through. If no, the browser gets redirected to the YunoHost login page, where the credentials are checked against LDAP.
After a successful login, SSOWAT sets a signed cookie named yunohost_session and — this is the part app developers care about — injects the user's LDAP attributes (uid, mail, displayName) into HTTP headers on the way to the app. A well-packaged app can read those headers and skip its own login screen entirely, or at least pre-fill the profile.
How apps opt in
Packaged apps declare their posture in the manifest. Setting need_auth: true tells the packaging framework to put the app behind SSOWAT automatically; omitting it leaves the app public. This is why some of your installed apps drop you straight in after portal login while others are reachable by anyone with the URL.
A concrete check you can run
To confirm SSO is doing its job on your server, you don't need any tooling beyond a browser:
- In the admin panel, go to Users → List and confirm at least one user exists.
- Open a private browsing window and visit an app URL, e.g.
https://yourdomain.example/wordpress. You should be bounced to the YunoHost sign-in page rather than the app's own login. - Log in with the YunoHost user, then visit a second protected app. You should get in with no prompt — the session cookie is being honored across apps.
- Open your browser's developer tools and look at cookies for your domain. You should see
yunohost_session, a base64-looking signed token. Log out of the portal and confirm the cookie changes or disappears.
If step 2 shows the app's native login page instead of the YunoHost portal, the app is either packaged without need_auth or its permission settings allow visitors — check the app's permissions in the admin panel.
The trade-offs worth knowing
The design has two real limitations. First, the LDAP directory listens only on localhost. That's a sensible security default, but it means an external service — say, a device on your LAN or a VPS elsewhere — can't query YunoHost users directly. You'd need a secure tunnel or to go through YunoHost's API, which makes integration with non-YunoHost systems awkward by design.
Second, the pieces are coupled. Changing the LDAP admin password or the base DN isn't a one-line edit — SSOWAT's configuration has to stay in sync, and rotating the cookie signing key invalidates existing sessions. If you plan to touch any of this, test on a staging machine or a snapshot first; a mismatch here locks everyone out of every app at once.
There's also a trust boundary to be aware of: because apps consume identity from HTTP headers, anything that bypasses the proxy and reaches an app directly could spoof those headers. YunoHost's packaging handles this for standard installs, but if you hand-edit nginx config, keep the proxy as the only path to protected apps.
Where to go from here
For most home and small-team setups, the default configuration is exactly what you want: one account per person, one login per session, and per-app permissions managed from the admin panel. The actionable step is simply to audit it — walk through your installed apps, confirm which ones sit behind SSOWAT, and make sure anything holding private data has visitor access disabled. Five minutes of checking beats discovering your \"private\" wiki was public all along.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.