SSO Runbook — Keycloak / Authentik (self-hosted)¶
End-to-end setup for sign-in with a self-hosted OIDC provider. ~10 minutes from a clean Keycloak realm to a working "Sign in with Keycloak" button on the MFCloud console. Authentik follows the same shape — it's noted inline wherever its screens use different names.
What you'll end up with¶
- A dedicated realm (Keycloak) or application (Authentik) that only MFCloud uses.
- A confidential OIDC client with a redirect URI registered.
- A client ID + secret you'll paste into MFCloud's Settings → SSO.
Prerequisites¶
- Admin access to your Keycloak or Authentik instance.
- MFCloud master reachable at a stable HTTPS URL from both the IdP (server-to-server token exchange) and the browser doing the sign-in.
Why this runbook exists¶
Unlike Entra/Google/Okta, a self-hosted IdP has no fixed tenant URL — you're both the IdP admin and the MFCloud admin, so a couple of things that a SaaS IdP enforces for you become your own responsibility to get right:
- The Issuer URL must be reachable from the MFCloud master's server side,
not just from your browser. If Keycloak/Authentik lives behind a different
network segment than the master, the discovery-doc fetch (
/api/auth/oidc/start) will fail even though the browser can reach the IdP's login page fine. - Realms/applications you spin up for testing are easy to leave behind. Delete the test realm (or the whole VM, if it was disposable) once you've confirmed sign-in works — see Cleanup.
Step 1 — Create a realm (Keycloak) / application (Authentik)¶
Keycloak:
- Admin console → realm dropdown (top-left) → Create Realm.
- Realm name =
mfcloud(or whatever you like) → Create.
Authentik: create a new Application + Provider pair instead — Authentik doesn't have a separate realm concept; skip to Step 2 and pick OAuth2/OpenID Provider as the provider type.
Step 2 — Create the OIDC client¶
Keycloak:
- Clients → Create client.
- Client type = OpenID Connect, Client ID =
mfcloud-console→ Next. - Client authentication = On (this makes it a confidential client — you need a secret) → Next.
- Valid redirect URIs =
https://<your-mfcloud-host>/api/auth/oidc/callback→ Save. - Credentials tab → copy the Client secret.
Authentik: Provider type OAuth2/OpenID Provider, Client type = Confidential, Redirect URIs = the same callback URL, Signing Key = any available RSA key. The client ID/secret are shown on the Provider's detail page after creation.
Step 3 — Create a test user¶
Both platforms ship with no default users besides the bootstrap admin, and that admin account lives in a different realm/context than your new client — create a normal user to sign in with:
Keycloak: Users → Add user → fill in Username, Email, First name, Last name → Create → Credentials tab → Set password (untick Temporary so it doesn't force a reset on first login).
Fill in First/Last name, not just email
If Keycloak's realm has the default User Profile config (first/last name marked required), a user created without them gets bounced into a Verify Profile page mid-login instead of reaching MFCloud's callback — the flow doesn't fail, it just stalls on an extra Keycloak screen the first time. Filling both fields in at creation avoids it entirely.
Authentik: Directory → Users → Create, then set a password via the user's Set password action.
Step 4 — Paste into MFCloud¶
In the MFCloud console:
- Settings → 🔑 Single Sign-On (OpenID Connect).
- Fill in:
- Issuer URL — Keycloak:
https://<your-keycloak-host>/realms/mfcloud(note/realms/<name>, not/auth/realms/<name>— that older path was dropped in Keycloak 17+). Authentik:https://<your-authentik-host>/application/o/<slug>/. - Client ID — from Step 2.
- Client Secret — from Step 2.
- Sign-in Button Label —
Sign in with Keycloak(or your IdP's name). - Default Role —
Tenant Viewer. - Email Claim —
email. - Groups Claim —
groups(Keycloak includes this by default for realm roles/groups the client's scope allows; Authentik needs a Scope Mapping added to the provider to populate it). - Enable OIDC sign-in ✓.
- Save SSO Settings.
Step 5 — Test it¶
- Sign out of MFCloud.
- Login page → Sign in with Keycloak.
- Redirects to your IdP's own login form → authenticate → back to MFCloud dashboard.
- User avatar should show the test user's email.
Troubleshooting¶
| Symptom | Cause | Fix |
|---|---|---|
| Login form loads, but after submitting you land on a Keycloak "Update Account Information" / "Verify Profile" page instead of MFCloud | Test user is missing a required profile field (usually first/last name) | Fill in the missing field(s) on that page once, or set them on the user ahead of time (Step 3) |
400: Stale or missing OIDC flow cookie even though you clicked the button seconds ago |
You (or a test script) hit the master over plain HTTP. The flow cookie is Secure-flagged and browsers/HTTP clients never send it over an unencrypted connection |
Always test through the real HTTPS front end (Caddy), never a bare :8000 app port |
Discovery fails / /api/auth/oidc/start 502s |
The MFCloud master container can't reach the IdP's /.well-known/openid-configuration — common if the IdP is on an isolated test network |
Confirm curl <issuer>/.well-known/openid-configuration succeeds from the master's own host, not just your browser |
| Works for you, fails for a colleague on a different network | Issuer URL points at an address only reachable from your machine (e.g. a hosts file override) |
Use a real, universally-resolvable hostname for anything beyond a one-person test |
Cleanup¶
Self-hosted test IdPs tend to be disposable — a Keycloak/Authentik instance spun up just to validate the OIDC integration, not a production identity system. Once you've confirmed sign-in works:
- Settings → SSO → Enable OIDC sign-in ✗ (or point it at your real IdP instead).
- Delete the test realm/application at the IdP.
- Tear down the VM/container it was running in, if it was purpose-built for this test.