Skip to content
ricochet

Authentication

ricochet uses OpenID Connect (OIDC) for login, so you can connect any OIDC-compliant identity provider.

The OIDC provider must support:

  • Claims: email and profile
  • Grant Type: Authorization Code Flow
  • PKCE: code challenge with the S256 method

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.

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"
FieldRequiredDescription
issuer_urlYesYour OIDC provider’s issuer URL. Must start with https://
client_idYesOAuth client ID from your OIDC provider
client_secretNoOAuth 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_urlYesCallback URL users return to after login. Must be https://your-domain/oauth/callback
display_name_claimNoOIDC claim to use for the display name. Defaults to preferred_username
groups_claimNoName 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.
providerNoIdentity 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_intervalNoHow 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.

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.

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.

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.

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.

Auth0 does not send preferred_username for most connections, so set display_name_claim to name or email.

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.

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 = true

Or set the environment variable:

Terminal window
RICOCHET_AUTH__REQUIRE_AUTHENTICATION=true
SettingUnauthenticated User Access
require_authentication=falseCan view Explore page and public content only
require_authentication=trueRedirected 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.