Overview and requirements
OpenID Connect (OIDC) lets users sign in to Roxy-WI through an identity provider. You can configure multiple providers, give each one a login button, link existing users or create users on first sign-in, and map external groups to Roxy-WI groups and roles. Local and LDAP login remain available.
Screenshots show unsaved example values in the Roxy-WI demo. Use your own identity provider, domains and groups when configuring your installation.
This guide applies to Roxy-WI 9.1 and later. OIDC requires an active Enterprise or Premium subscription; existing Cloud subscriptions also support it. Only a super administrator can manage providers and mappings in Admin → OIDC.
- Use an HTTPS address for Roxy-WI that users' browsers can reach.
- The Roxy-WI web processes must be able to reach the provider's discovery, token, JWKS and, when configured, UserInfo endpoints.
- Create the target Roxy-WI groups before configuring default access or mappings. See groups and roles.
- Keep a working local administrator session while testing the first provider.
Roxy-WI uses the authorization code flow, checks the login state and nonce, and validates signed ID tokens against the provider's JWKS. The current flow does not send PKCE parameters; a client that requires PKCE will not work with this implementation.
Connect an identity provider
- Set
ROXYWI_PUBLIC_URLto the external Roxy-WI origin, for examplehttps://roxy-wi.example.com, without a trailing slash. Apply it to all web processes and restart or recreate them after changing the environment. This is especially important behind a reverse proxy. - Register a web application at the identity provider for authorization code login. Obtain its client ID, client secret when required, and discovery URL. Configure it to return the claims described below.
- Open Admin → OIDC → Add. Enter a stable Slug, such as
company-sso, a Login button label, such asCompany SSO, the client credentials and the Discovery URL. - Start with Scopes set to
openid email profile. Add any scope your provider needs to return group membership. Configure Default group, Default role and the user policies below. Clear Enabled during initial setup, then choose Save provider. - Open the saved provider's action menu and choose Edit. Copy the displayed Callback URL into the identity provider's allowed redirect URIs. Match the scheme, host, port and path exactly.
- If using external groups, open Manage group mappings from the provider's action menu, add the required mappings and save them.
- Enable and save the provider, then test it in a separate browser session. The login page shows Sign in with Company SSO for the example label.
With the example origin and slug above, the callback URL is:
https://roxy-wi.example.com/oidc/company-sso/callbackUse the URL displayed by your installation. Changing the slug changes the callback path, so update the identity provider's redirect URI at the same time. Without ROXYWI_PUBLIC_URL, Roxy-WI builds the callback from the incoming request.
Provider settings
| Field | Configuration |
|---|---|
| Slug | A unique identifier of 2–64 characters. Use lowercase letters, digits, hyphens or underscores; start with a letter or digit. It forms part of the login and callback URLs. |
| Login button label | The provider name shown on the login page, for example Company SSO. |
| Client ID / Client secret | Credentials issued for the Roxy-WI application. When editing, leave the secret empty to retain the stored value. Enter a replacement to update it. |
| Discovery URL | The provider's OpenID configuration document. Use the URL supplied by your provider; its path can include a tenant or realm. |
| Issuer | Normally read from discovery. If specified explicitly, it must match the ID token's iss claim exactly. |
| Scopes | Defaults to openid email profile. The openid scope is required. Request provider-specific group scopes when needed. |
| Advanced endpoints and claims | Optional explicit authorization, token, UserInfo and JWKS URLs, plus claim names and allowed email domains. Explicit endpoint values take precedence over discovery. |
| Enabled | Shows the provider on the login page and permits login and callback requests. Disabling it prevents new OIDC logins through that provider. |
If you do not use discovery, supply Issuer, Authorization endpoint, Token endpoint and JWKS URI. UserInfo endpoint is optional. Without discovery metadata, ID token signature verification defaults to RS256.
When a UserInfo endpoint is configured or advertised by discovery, Roxy-WI fetches it during login. Its subject must agree with the ID token when present. If the same claim appears in both responses, the verified ID token value takes precedence.
Client secrets are encrypted with the installation's existing credential key, [main] secret_phrase (or its ROXYWI_SECRET_PHRASE override), and are not returned by the provider API. Keep that key when upgrading or moving the installation.
Claims
Claim names are configured under Advanced endpoints and claims. Direct names and dotted paths are supported, such as realm_access.roles for a nested groups value.
| Field and default | How Roxy-WI uses it |
|---|---|
Subject claim: sub | A stable user identifier. The issuer and subject identify the linked Roxy-WI account; use a value that does not change when the user's name or email changes. |
Email claim: email | Required to create a user and used for email linking and domain restrictions. |
Username claim: preferred_username | Used when creating a local username. If absent, the email name is used; usernames are normalized and made unique. |
Groups claim: groups | External group names for mapping. A JSON array is recommended. Comma-separated strings and strings containing a JSON array are also accepted. |
email_verified | The fixed claim checked by Require verified email. Have the provider return the boolean true after verifying the address. |
For example, these application claims provide a verified email and one external group. This is an illustrative claims fragment, not a complete ID token:
{
"sub": "user-12345",
"email": "operator@example.com",
"email_verified": true,
"preferred_username": "operator",
"groups": ["roxy-operators"]
}Changing a claim name in Roxy-WI does not make the identity provider emit it. Configure the application's scopes or claim mappings at the provider as well.
User creation and linking
| Option | Default and behavior |
|---|---|
| Auto-create users | Off. Enable it to create a Roxy-WI user when no linked or eligible existing account is found. A non-empty email is required. |
| Link existing users by email | On. At first login, an existing local account with the same email can be linked. Matching ignores case. Disabled accounts and duplicate email matches are rejected. |
| Require verified email | On. Login requires an email and a positive email_verified claim. Keep this enabled when linking accounts by email and configure the provider to supply the claim. |
| Allowed email domains | Empty. No domain restriction. To restrict login, enter comma-separated domain names, such as example.com, example.org. Matching ignores case and is exact; subdomains must be listed separately. |
| Default group / Default role | Access for newly created users when group synchronization is off or there are no active mappings. Select the intended group explicitly; the default role is guest (read-only access). |
For an existing team, create local accounts with unique email addresses and group memberships, then use email linking. To provision users at first login, enable Auto-create users and configure either default access or matching external groups.
If an email already belongs to a local user and email linking is off, login is rejected rather than creating a second account. After the first successful link, the issuer and subject identify the account. A disabled linked user cannot sign in.
Groups and roles
Open a provider's Manage group mappings action, then choose New mapping. Set the External group, target Roxy-WI group, Role, Priority and Active state. For the claims example above, map roxy-operators to your existing Operations group and the role those operators need.
- Sync mapped groups is on by default. Active mappings run at each OIDC login; this is not a background directory synchronization.
- External group names match without regard to case. A user can match several mappings and receive membership in several Roxy-WI groups.
- When synchronization is enabled and active mappings exist, newly created users must match a mapping. The default group is not a fallback. Existing users can still sign in if they retain another membership.
- Remove missing mapped groups is off by default. Enable it to remove memberships in groups targeted by the provider's active mappings when they are no longer matched. Other memberships are retained. Disabling or deleting a mapping does not itself remove existing membership.
- Mappings run from lower to higher priority, then by mapping ID. If several matching rules target the same Roxy-WI group, the last rule applied determines its role. Avoid conflicting rules for one group.
If no memberships remain, login fails. User creation, identity linking and group synchronization are transactional: a failed group assignment does not leave a newly created user behind. OIDC login still uses Roxy-WI's group, role and service permissions.
Verify sign-in
- Use a separate browser session to open the Roxy-WI login page and select the provider's button.
- Authenticate at the identity provider and confirm that the browser returns to the registered callback URL, then to Roxy-WI.
- Check the resulting account, current group, available groups and role. Confirm that it can access the intended servers and services.
- Test a second login to confirm the same account is reused. If testing mapped group removal, change the test user's external membership and start a new OIDC login; existing sessions are not continuously resynchronized.
For multiple web replicas, use the same persistent Flask session secret (ROXYWI_SECRET_KEY or shared configured secret file) and the same credential encryption key. Otherwise the callback can reach a worker that cannot read the login session or decrypt the client secret.
Troubleshooting
Login failures return an error code and message. Use the code to identify the failed stage:
| Symptom or error | What to check |
|---|---|
| OIDC tab or login button is missing | Check the active subscription and provider's Enabled state. Only super administrators see the OIDC administration tab. |
| Redirect URI mismatch | Compare the displayed callback with the URI registered at the provider. Check ROXYWI_PUBLIC_URL, HTTPS, port and slug. |
oidc_state_invalid | Start a fresh login from Roxy-WI in one tab. Keep cookies enabled and use the same HTTPS host throughout. For multiple replicas, check the shared Flask session secret. |
oidc_metadata_error, oidc_jwks_error, oidc_userinfo_failed | Check endpoint URLs, DNS, TLS trust and connectivity from the Roxy-WI web processes. Discovery and JWKS must return JSON. If discovery advertises UserInfo, that endpoint must work too. |
oidc_id_token_missing, oidc_id_token_invalid | Check the openid scope, client ID, exact issuer, signing keys and algorithm, token expiry and clock synchronization. Restart login if its nonce was lost. |
oidc_email_missing, oidc_email_not_verified, oidc_domain_denied | Check the email claim name, email_verified and exact allowed domain list. Adjust the provider's claim configuration to meet the selected policy. |
oidc_user_not_found, oidc_email_already_exists, oidc_email_ambiguous | Check auto-creation and email-linking settings, and ensure the email identifies a single local account. |
oidc_group_mapping_not_matched, oidc_user_has_no_group | Check the groups claim, active mappings and existing Roxy-WI memberships. With active mappings, a new user needs a match. |
oidc_user_disabled, oidc_provider_not_found | Check the local user's enabled state and whether the provider still exists, is enabled and uses the expected slug. |
oidc_authorization_error, oidc_callback_failed | Review the provider's authorization response and the Roxy-WI login logs. Check client credentials, token endpoint connectivity and the client's authorization-code settings. |
See internal logs for login diagnostics and pricing for subscription availability.