Generic OIDC lets you sign in to Buttons through any OpenID Connect provider that supports Discovery, the Authorization Code flow, PKCE, and nonce, not just the named providers Buttons lists separately (Google, Microsoft Entra ID, GitHub, Okta).
Before you begin#
- An Enterprise license: SSO is gated to this tier.
- Buttons' public address configured (Environment Settings → Editor Listen Address, or equivalent): the callback URL is built from this, and OIDC won't work without it.
- Your identity provider's Issuer URL, and the ability to register a Client ID/Secret and a redirect URI with it.
- ID tokens signed with RS256 or ES256: Buttons doesn't support other signing algorithms.
- Open Settings → SSO and create a new connection with Provider set to Generic OIDC.
- Before filling in the form, select Setup guide for a copyable callback URL and a short checklist.
- In your identity provider, register a confidential web application and set its redirect/callback URI to the copied value.
- Note the application's Client ID and Client Secret, and the provider's Issuer URL exactly as its own discovery document advertises it.
If Buttons' public address isn't configured yet, the setup guide shows a warning instead of a callback URL, and the connections list shows the same warning until it's set.
- Enter a Display name for this connection.
- Enter the Client ID and Client secret from your provider.
- Enter the Issuer URL. It must use HTTPS unless the host is specifically allowlisted for HTTP (intended for local testing, not production).
- Add any Additional scopes beyond the defaults Buttons always requests (
openid, profile, email). - Save.
Note
The Client Secret is stored directly on this connection's own record, not through the same Secrets vault used for connection credentials elsewhere in Buttons. Treat access to the SSO connection list itself as sensitive.
Map claims to roles#
Once the connection exists, a Role mappings section appears. Add a mapping with a Claim name (for example, groups), a Claim value matching what your provider actually sends, and the Local role it should grant. You can add several mappings pointing at the same role, or several roles from different claim values: there's no one-to-one restriction.
Use
Test mappings to paste a sample of decoded ID-token claims and see which roles it would grant, without contacting your provider: useful for confirming a mapping is shaped correctly before a real user tries to sign in. See
Map identity claims to roles for how this actually behaves at sign-in time, including what happens when a user's claims change on a later login.
Test the connection#
There's no separate "Test connection" button for OIDC: checking discovery and issuer configuration happens automatically the moment anyone selects this sign-in option, before they're redirected to your provider. If the issuer is unreachable, doesn't match, or doesn't advertise a supported signing algorithm, the error appears inline on the login page immediately, rather than after a full round trip through your provider.
Confirm the connection actually works by signing in with it yourself once, using an account your mapped roles cover.
Recover from a misconfiguration#
Local username/password sign-in stays available on the same login page no matter what state this connection is in: a broken OIDC connection doesn't remove it. If something's wrong, the login page shows a plain-language message rather than a raw error:
What a user sees | What it means |
|---|
"Single Sign-On is not ready because the external Buttons address is not configured." | Buttons' public address isn't set: configure it before OIDC can work at all. |
"This sign-in connection is not properly configured." | The Client ID or Client Secret is missing. |
An error before being redirected to your provider (issuer mismatch, discovery failure, unsupported signing algorithm) | The Issuer URL or provider configuration is wrong: Buttons catches this before sending the user anywhere. |
"Sign-in failed. Please try again." (after returning from your provider) | The Client Secret is likely wrong, or the token exchange failed. |
"Your sign-in session has expired. Please try again." | The user took too long, or reused an old sign-in link. |
If you get stuck#
What you see | What to try |
|---|
The setup guide shows no callback URL. | Configure Buttons' public address first: the callback URL can't be generated without it. |
Sign-in fails immediately, before reaching your provider. | Check the Issuer URL matches your provider's discovery document exactly, and that it's HTTPS (or explicitly allowlisted). |
Sign-in fails right after returning from your provider. | Double-check the Client Secret: this is the most common cause of a post-redirect failure. |
A user signs in but doesn't get the role you expected. | Use Test mappings with a real sample of their claims to check your mapping actually matches what the provider sends. |
You're worried about being locked out while testing. | You won't be: local sign-in remains available on the same login page throughout, regardless of this connection's state. |
Where to go next#