Authentication
ricochet uses OpenID Connect (OIDC) for login, so you can connect any OIDC-compliant identity provider.
Requirements
Section titled “Requirements”The OIDC provider must support:
- Claims:
emailandprofile - Grant Type: Authorization Code Flow
- PKCE: code challenge with the
S256method
ricochet uses the subject identifier (sub) as the unique user ID.
It collects the email claim for future SMTP features.
Every sign-in sends a PKCE challenge, then sends the matching verifier in the token exchange.
Your client registration must allow PKCE.
If your provider has a PKCE setting, set it to S256.
You cannot turn PKCE off.
Since PKCE protects the flow, client_secret is optional and ricochet can run as a public client.
The one exception is Microsoft Entra group and avatar sync, which needs the secret to call Microsoft Graph.
Configuration
Section titled “Configuration”Add this to your ricochet-config.toml:
[auth.oidc]issuer_url = "https://auth.example.com/"client_id = "your_client_id"client_secret = "your_client_secret"redirect_url = "https://your-ricochet-domain.com/oauth/callback"display_name_claim = "preferred_username" # Optional, defaults to "preferred_username"groups_claim = "groups" # Optional, defaults to "groups"Configuration Fields
Section titled “Configuration Fields”| Field | Required | Description |
|---|---|---|
issuer_url | Yes | Your OIDC provider’s issuer URL. Must start with https:// |
client_id | Yes | OAuth client ID from your OIDC provider |
client_secret | No | OAuth client secret from your OIDC provider. Leave it out to register ricochet as a public client. Microsoft Entra group and avatar sync needs it. |
redirect_url | Yes | Callback URL users return to after login. Must be https://your-domain/oauth/callback |
display_name_claim | No | OIDC claim to use for the display name. Defaults to preferred_username |
groups_claim | No | Name of the OIDC claim that holds the user’s groups. The value may be an array of strings, a single string, or a comma-separated string. Leave it out to turn off group sync at login. |
provider | No | Identity provider type. Set to "entra" for Microsoft Entra ID. For all other providers, leave it out or set it to "oidc". With "entra", groups_claim defaults to "groups" and background directory sync turns on. |
sync_interval | No | How often, in minutes, to run background group sync from the IdP directory. Works only with provider = "entra". Leave it out to sync groups at login only. |
SSO Groups
Section titled “SSO Groups”When groups_claim is set (default "groups"), ricochet reads the user’s groups from that claim in each ID token at login.
It stores a local copy of those groups.
You can then grant a role on a content item to a group name in the collaborators dialog.
Any user whose ID token held that group at their last login gets the role.
Keep these points in mind:
- Groups refresh on every login. If you add a user to a group in your IdP after their last ricochet login, they get the role only after they sign in again.
- Names must match exactly, including case. The group name you type in the collaborators dialog must match the string in the ID token byte for byte.
Microsoft Entra ID (Azure AD)
Section titled “Microsoft Entra ID (Azure AD)”Issuer URL
Section titled “Issuer URL”With Microsoft Entra ID, you must use the v2.0 issuer URL.
The v1 issuer (https://sts.windows.net/{tenant-id}/) returns a non-standard discovery document that ricochet’s OIDC client cannot read.
[auth.oidc]provider = "entra"issuer_url = "https://login.microsoftonline.com/{tenant-id}/v2.0"client_id = "your_client_id"client_secret = "your_client_secret"redirect_url = "https://your-ricochet-domain.com/oauth/callback"Replace {tenant-id} with your Azure tenant ID.
Groups claim
Section titled “Groups claim”Entra does not send a groups claim by default.
Turn it on in the app registration under Token configuration → Add groups claim.
Pick Group ID (the default) or sAMAccountName, based on what your tenant supports.
User avatars
Section titled “User avatars”Standard OIDC providers fill user avatars from the picture claim.
Entra leaves out that claim and serves photos only from Microsoft Graph.
With provider = "entra" set, ricochet fetches each user’s photo at login from GET /users/{id}/photo/$value.
It resizes the photo to a 128×128 PNG and stores it, but never overwrites an avatar the user uploaded.
In Auth0, create a Regular Web Application.
Add https://your-ricochet-domain.com/oauth/callback to its Allowed Callback URLs.
Copy the Domain, Client ID, and Client Secret from the app’s Settings tab.
[auth.oidc]issuer_url = "https://{tenant}.auth0.com/"client_id = "your_client_id"client_secret = "your_client_secret"redirect_url = "https://your-ricochet-domain.com/oauth/callback"display_name_claim = "name"groups_claim = "https://ricochet.example.com/groups"Replace https://{tenant}.auth0.com/ with your app’s Domain, or with your Auth0 custom domain if users sign in through one.
Display name
Section titled “Display name”Auth0 does not send preferred_username for most connections, so set display_name_claim to name or email.
Groups claim
Section titled “Groups claim”Auth0 puts no groups in the ID token. To share content with groups, add a post-login Action under Actions → Triggers → post-login. The Action copies the user’s Auth0 roles into a namespaced claim:
exports.onExecutePostLogin = async (event, api) => { api.idToken.setCustomClaim( "https://ricochet.example.com/groups", event.authorization?.roles ?? [], );};Set groups_claim to the full claim name, including the https:// namespace.
In the collaborators dialog, grant a role on content to an Auth0 role name, spelled exactly as in Auth0.
Requiring Authentication
Section titled “Requiring Authentication”By default, users who are not signed in can browse the “Explore” page and view public content.
To require login for all access, turn on the require_authentication option:
[auth]require_authentication = trueOr set the environment variable:
RICOCHET_AUTH__REQUIRE_AUTHENTICATION=trueBehavior
Section titled “Behavior”| Setting | Unauthenticated User Access |
|---|---|
require_authentication=false | Can view Explore page and public content only |
require_authentication=true | Redirected to sign-in page on all routes |
With require_authentication on, users see a full-screen login page with SSO sign-in.
With it off (the default), users who are not signed in can browse public content.
They see a sign-in prompt in the sidebar for protected features such as deployment, API keys, and settings.