Configuring Discourse (identity-only pattern)
Configuring Discourse (identity-only pattern)
Pattern: identity only. Discourse authenticates users through Keycloak but does no group or role mapping. The IdP answers one question, "who is this user," and Discourse handles authorization internally with its own trust levels and groups. Use this pattern for any application that needs single sign-on but manages permissions on its own.
Keycloak side
Create a client in the realm:
| Setting | Value | Why |
|---|---|---|
| Client ID | discourse |
Matches the client ID configured in Discourse. |
| Client authentication | On (confidential) | Discourse holds a client secret and exchanges the auth code on a back channel. |
| Standard flow | Enabled | Authorization-code flow. |
| PKCE method | S256 | Proof key for code exchange; hardens the code flow against interception. |
| Valid redirect URIs | https://forum.example.org/auth/oidc/callback |
Where Keycloak returns the user after login. |
No client scopes beyond the defaults are needed. Because Discourse does not consume groups, there is no group-membership mapper and no custom scope to create. This is the whole reason the identity-only pattern is the simplest one: you stop after the client exists.
Discourse side
Discourse's OpenID Connect support is provided by its official connector, configured entirely from the admin settings UI (Admin → Settings → search "openid"). The relevant settings:
| Setting | Value | Notes |
|---|---|---|
| openid connect enabled | checked | Turns on the connector. |
| openid connect discovery document | https://auth.example.org/realms/landisfam/.well-known/openid-configuration |
Discourse resolves all endpoints from this; you never hand-configure token or authorize URLs. |
| openid connect client id | discourse |
Must match the Keycloak client ID. |
| openid connect client secret | (from Keycloak, stored in the password manager) | The confidential client's secret. |
| openid connect authorize scope | openid email profile |
The three standard scopes. No groups here, by design. |
| openid connect match by email | checked | Links a Keycloak identity to an existing Discourse account by email address. |
| openid connect use pkce | checked | Must match the S256 method set on the Keycloak client. |
Gotchas, in context
- Match-by-email is a decision, not a default. Enabling "match by email" means a user who already had a local Discourse account gets linked to their Keycloak identity on first SSO login, rather than getting a second, empty account. Leave it off and you can end up with duplicate accounts. Turn it on only if you trust that email addresses in Keycloak are verified, because email-matching is exactly as trustworthy as your IdP's email verification.
- PKCE has to agree on both ends. If Keycloak requires S256 and Discourse doesn't send a PKCE challenge (or vice versa), login fails. Set it in both places.
Adapt this for…
Any application that offers "OIDC / OpenID Connect login" as a plugin or built-in feature and handles its own authorization: forums, wikis without group needs, dashboards, status pages. The recipe is always the same three moves: confidential client in Keycloak, point the app at the discovery document, request openid email profile. If the app never needs to know a user's role from the IdP, you are done here.