Sso Identity
SSO & Identity Management
Centralized authentication and authorization for all web services using Kanidm and OAuth2 Proxy.
Overview
This repository uses Kanidm as the core identity provider. It supports modern authentication standards like WebAuthn (YubiKey), OIDC, and LDAP. To protect web services that don’t natively support OIDC, we use the Forward Auth pattern with OAuth2 Proxy.
Key Components
- Kanidm (
modules/services/auth/kanidm.nix): The “Source of Truth” for users, groups, and credentials. - OAuth2 Proxy (
modules/services/auth/oauth2-proxy.nix): A gateway that handles the OIDC login flow with Kanidm. - Nginx (
modules/services/web/nginx.nix): Usesauth_requestto intercept requests and verify authentication with OAuth2 Proxy before allowing access to backend services.
Deployment Logic
Where does it run?
- Kanidm: Typically runs on a stable, persistent node like
lab-matrixorbio-alpha. It is exposed to the internet via the VPS (vps-pacman) using our standard Nginx reverse proxy. - OAuth2 Proxy: Runs on the same node as Nginx (usually the VPS) to provide fast authentication checks.
Traffic Path
- User Request:
https://git.alienzj.org-> Hits VPS Nginx. - Intercept: Nginx asks OAuth2 Proxy: “Is this user logged in?”.
- Redirect: If no, the user is sent to
https://id.alienzj.org(Kanidm) to login with their password and YubiKey. - Authorize: After login, Kanidm sends the user back to OAuth2 Proxy, which sets a secure cookie for
.alienzj.org. - Access: Nginx now sees the user is authenticated and proxies the traffic to the Homelab Backend over Tailscale.
Usage: Protecting a Service
To protect any web service with Kanidm SSO, simply set kanidm.enable = true in its module configuration.
Example: Protecting Glance
modules.services.web.glance = {
enable = true;
kanidm.enable = true; # This activates the Nginx 'auth_request' protection
};
Supported Services
Currently, the following services have integrated SSO support:
- Glance (Dashboard)
- HedgeDoc (Markdown Editor)
- Linkwarden (Bookmarks)
- Discourse (Forum)
- FreshRSS (RSS Reader)
- Grocy (ERP)
- Affine (Knowledge Base)
- Forgejo (Git)
- Vaultwarden (Password Manager)
- Stirling-PDF (PDF Tools)
Note: Services like Forgejo and Nextcloud often have native OIDC support, which is preferred for better user mapping if supported.
Frequently Asked Questions
Can services work without SSO?
Yes. If kanidm.enable = false (the default), the service will use its own internal login system. You can always reach your services directly via Tailscale IPs if the SSO system is down.
Why use SSO?
- Security: Enforce Hardware MFA (YubiKey) across every single application.
- Convenience: Login once, access everything.
- Centralization: Disable one user in Kanidm, and they lose access to every service instantly.
How to configure a new OAuth2 Client in Kanidm?
The oauth2-proxy-env secret is a secure environment file that oauth2-proxy uses to authenticate with Kanidm.
1. Generate a Cookie Secret
OAuth2 Proxy needs a random string to encrypt its session cookies. Run this command to generate one:
python3 -c 'import os,base64; print(base64.urlsafe_b64encode(os.urandom(32)).decode())'
2. Register OAuth2 Proxy in Kanidm
On the machine running Kanidm (e.g., lab-matrix), create the OIDC client:
kanidm oidc create oauth2_proxy "OAuth2 Proxy" https://auth.alienzj.org/oauth2/callback
This command will output a Client ID and a Client Secret.
3. Create the Encrypted Secret File
On your development machine, create the secret using agenix:
agenix -e secrets/oauth2-proxy-env.age
Paste the following into the file (replacing the values):
OAUTH2_PROXY_CLIENT_ID=<your-kanidm-client-id>
OAUTH2_PROXY_CLIENT_SECRET=<your-kanidm-client-secret>
OAUTH2_PROXY_COOKIE_SECRET=<your-generated-cookie-secret>
4. Map the Secret in Nix
Ensure your host configuration (e.g., hosts/vps-pacman/modules/secrets.nix) points to the encrypted file:
age.secrets.oauth2-proxy-env.file = ../../secrets/oauth2-proxy-env.age;