A generic OpenID Connect (OIDC) SSO provider for Mattermost. Any OIDC-compliant IdP should work; we have only verified it against Entra ID.
- OIDC Discovery: authorization, token, and userinfo endpoints resolved from
.well-known/openid-configuration - Account linking: existing Mattermost accounts with a matching email are linked to OIDC on first login
- Attribute sync on each login (via Mattermost's OAuth flow)
- Delivered as a Go module plus a small patch against upstream Mattermost — no fork
- Mattermost v11.10.0 (the version the current patch targets)
- Mattermost v11.9.1 also supported via
patches/mattermost-v11.9.1.patch - Mattermost v11.8.5 also supported via
patches/mattermost-v11.8.5.patch - Mattermost v11.7.9 also supported via
patches/mattermost-v11.7.9.patch - Mattermost v11.6.6 also supported via
patches/mattermost-v11.6.6.patch - Mattermost v11.5.7 also supported via
patches/mattermost-v11.5.7.patch - Mattermost v11.4.5 also supported via
patches/mattermost-v11.4.5.patch - Mattermost v11.3.3 also supported via
patches/mattermost-v11.3.3.patch - Mattermost v11.2.4 also supported via
patches/mattermost-v11.2.4.patch - Mattermost v11.1.3 also supported via
patches/mattermost-v11.1.3.patch - Mattermost v11.0.7 also supported via
patches/mattermost-v11.0.7.patch - Mattermost v10.11.10 also supported via
patches/mattermost-v10.11.10.patch - Go 1.26.4+
Older patches need an older checkout: Mattermost v11.6 changed the
einterfaces.OAuthProviderinterface (GetUserFromJSONgained asettings *model.SSOSettingsparameter). The module at HEAD implements the new interface, so the v11.5.7-and-older patches must be used with this repository checked out at the commit that introduced them.
Why this exists: Mattermost Team Edition (the libre/AGPL build) ships SAML, Google, and Microsoft 365 SSO behind an enterprise license — only GitLab SSO is enabled there. Many self-hosted deployments worked around this by pointing Mattermost's GitLab SSO at a GitLab instance that itself federated to the real IdP. In v11.0, GitLab SSO has also been moved out of Team Edition, so even that workaround is gone. This module restores OIDC directly in Team Edition, letting Mattermost talk to any OIDC IdP without a license or a GitLab intermediary.
git clone https://github.com/toowoxx/mattermost-oidc.gitcd mattermost-oidc
nix develop # Sets up Go 1.24 and GOPRIVATE automatically
go test ./...
go build ./...There is no Mattermost fork — the integration is a git apply against an upstream checkout. Clone it as a sibling of this repository:
git clone --depth 1 --branch v11.10.0 https://github.com/mattermost/mattermost.git ../mattermostApply the OIDC patch. It adds the go.mod require/replace, the main.go blank import, removes the email-user guard in user.go, and opens the OpenID frontend props without a license check:
cd ../mattermost && git apply ../mattermost-oidc/patches/mattermost-v11.10.0.patch(Optional) For an AGPL-only build, remove the enterprise directory and strip its import:
rm -rf server/enterprise
sed -i '/Enterprise Imports/d; /github.com\/mattermost\/mattermost\/server\/v8\/enterprise/d' \
server/cmd/mattermost/main.goCreate a go.work in the common parent so the server resolves mattermost-oidc locally:
cd ..
cat > go.work <<'EOF'
go 1.26.4
use (
./mattermost/server
./mattermost/server/public
./mattermost-oidc
)
EOFNote: server/public must be in the use list — the Mattermost server references in-tree server/public symbols that are newer than the tagged release on the module proxy, so omitting it breaks the build. This mirrors Mattermost's own make setup-go-work.
Note: Mattermost doesn't publish server/v8 to the Go module proxy. Set GOPRIVATE=github.com/mattermost/* when building.
In config.json or via environment variables:
{
"OpenIdSettings": {
"Enable": true,
"Id": "your-client-id",
"Secret": "your-client-secret",
"DiscoveryEndpoint": "https://your-idp.com/.well-known/openid-configuration",
"Scope": "openid email profile",
"ButtonText": "Login with SSO",
"ButtonColor": "#0058CC"
}
}Or using environment variables:
MM_OPENIDSETTINGS_ENABLE=true
MM_OPENIDSETTINGS_ID=your-client-id
MM_OPENIDSETTINGS_SECRET=your-client-secret
MM_OPENIDSETTINGS_DISCOVERYENDPOINT=https://your-idp.com/.well-known/openid-configurationcd mattermost/server
make build
./bin/mattermost serverSee docs/deployment-guide.md for the Docker build.
| Setting | Type | Default | Description |
|---|---|---|---|
Enable |
bool | false |
Enable OIDC authentication |
Id |
string | "" |
OAuth client ID |
Secret |
string | "" |
OAuth client secret |
DiscoveryEndpoint |
string | "" |
OIDC discovery URL. When set, AuthEndpoint/TokenEndpoint/UserAPIEndpoint are resolved from it. |
AuthEndpoint |
string | "" |
Authorization endpoint (ignored if DiscoveryEndpoint is set) |
TokenEndpoint |
string | "" |
Token endpoint (ignored if DiscoveryEndpoint is set) |
UserAPIEndpoint |
string | "" |
UserInfo endpoint (ignored if DiscoveryEndpoint is set) |
Scope |
string | "openid email profile" |
OAuth scopes to request |
ButtonText |
string | "OpenID Connect" |
Login button text |
ButtonColor |
string | "#145DBF" |
Login button color |
| OIDC Claim | Mattermost Field | Notes |
|---|---|---|
sub |
AuthData |
Unique user identifier (required) |
email |
Email |
Required, lowercased |
email_verified |
EmailVerified |
Passed through from the IdP |
preferred_username |
Username |
Sanitized via CleanUsername; falls back to the local part of email |
given_name |
FirstName |
|
family_name |
LastName |
|
name |
FirstName + LastName |
Used when given_name/family_name are absent; split on the first space |
Entra ID is what we use:
- Register a new application in Entra ID.
- Set the redirect URI to
https://your-mattermost.com/signup/openid/complete. - Create a client secret.
- Discovery endpoint:
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration.
Other OIDC-compliant IdPs should work the same way — point at their discovery endpoint and supply client ID/secret. We just haven't run them.
With the patch applied, IsSameUser allows an existing Mattermost user (any non-OIDC auth service) to be linked to their OIDC account on first login if the email matches. This is always-on — there is no toggle.
Verified cases: GitLab → OIDC and password/email auth → OIDC.
Other source services (google, office365, saml, ldap) are handled symmetrically in code (openid/openid.go), but we have not exercised those paths in production.
To disable linking, revert the server/channels/app/user.go hunk in the patch. The main.go, client.go, and go.mod hunks are required regardless.
- State parameter validation is handled by Mattermost's OAuth core (timestamp, nonce, signature; one-time use; 30-minute expiry).
subis used asAuthData— a stable identifier that does not change when the user's email or username changes.- HTTPS is required for OIDC endpoints in production.
AGPL-3.0 — see LICENSE.