Skip to content

OpenID Connect

Connect your own identity provider over OpenID Connect, on Team and above. It works with any standards-compliant provider, including Okta, Auth0, JumpCloud, OneLogin, PingOne, Keycloak and Authentik. For: Admins and Owners.

  • Verify your email domain under Settings → Verification. SafeHanded accepts a sign-in from your provider only for email addresses in domains your organisation has verified, whatever the provider says, so nobody can use a provider they control to sign in as someone else. A sign-in whose ID token says email_verified: false is refused too, so people who register themselves in your provider can’t claim an address they haven’t proven.
  • In your provider, create a web application (sometimes called a confidential client) that uses the authorization code flow. Note its client ID and client secret.
  1. Go to Settings → Integrations → Connect and choose OpenID Connect.
  2. Enter the issuer URL (the address before /.well-known/openid-configuration) and choose Test discovery.
  3. Enter the client ID and client secret, and how your provider expects the secret (HTTP Basic is the usual default).
  4. Sign-in is invite-only unless you turn on Provision new members on first sign-in for your verified domains. Then Save.
  5. On the connection’s Settings tab, copy the redirect URI into your provider’s allowed redirect or callback URLs. If your provider asks for an initiate login URI, copy that too.

If your provider wants the redirect URI before it issues a client, save the connection with the issuer and client empty. It waits, signing nobody in, while you register the redirect URI; then add the issuer, client ID and secret on the Settings tab to finish. The issuer can’t change after that.

Okta and Keycloak have been tested end to end. The notes for the others are checked against each provider’s own documentation; if what you see doesn’t match, email support@safehanded.com.

Okta. Use the issuer https://your-org.okta.com/oauth2/default. On that authorization server, make sure an access policy allows the authorization-code grant for your app, and add a groups claim if you want group-based provisioning.

Auth0.

  • Create a Regular Web Application. The issuer is https://your-tenant.<region>.auth0.com/, or your custom domain if people sign in on it.
  • Keep the signing algorithm at RS256 (Advanced Settings → OAuth). SafeHanded refuses HS256.
  • Under Credentials, match Authentication Method to what you chose in SafeHanded (Client Secret (Post) or (Basic)).
  • People must have verified their email in Auth0, or have email_verified set when you create them.
  • Auth0 has no groups claim, and it silently drops a custom claim named groups or roles. Add groups with a post-login Action using a namespaced name, for example api.idToken.setCustomClaim('https://safehanded.com/groups', event.authorization.roles), then set the groups claim in SafeHanded to that exact name.

JumpCloud.

  • Create an OIDC custom application. The issuer depends on your region: https://oauth.id.jumpcloud.com/ (US), https://oauth.id.eu.jumpcloud.com/ (EU) or https://oauth.id.in.jumpcloud.com/ (India).
  • Tick both Email and Profile under Standard Scopes.
  • Set Client Authentication Type to match SafeHanded (Client Secret Basic is the usual choice).
  • Paste the redirect URI, and use the initiate login URI as the Login URL.
  • For groups, turn on Include group attribute and name it groups (or set SafeHanded’s groups claim to the name you chose). Only groups bound to the application are sent.
  • Bind a user group to the application, or nobody can sign in. Keep sub as the JumpCloud user ID.

OneLogin.

  • Create an OpenId Connect (OIDC) app with Application Type Web. The issuer is https://your-subdomain.onelogin.com/oidc/2.
  • Match the Token Endpoint authentication method to SafeHanded.
  • For groups, add groups under Scopes and claims in SafeHanded, and in OneLogin set the Groups parameter to User Roles with Semicolon Delimited input (Multi-value output).
  • Use the initiate login URI as the Login URL.

Microsoft Entra ID. Most organisations should use the built-in Microsoft connection instead. If you need a generic OIDC connection:

  • Register a Web platform app with a client secret. Use your tenant’s issuer, https://login.microsoftonline.com/<tenant-id>/v2.0.
  • Use the preferred_username email claim unless you have added email as an optional claim.
  • Groups arrive as object IDs (GUIDs), so use those in group → role mapping, or send app roles and set the groups claim to roles. Someone in more than 200 groups gets no groups claim and falls back to your default rule.
  • Apps with a custom signing key aren’t supported.

Members choose Continue with single sign-on on the sign-in page and enter their work email; SafeHanded sends them to your provider. A sign-in started from your provider’s dashboard uses the initiate login URI.

If sign-in fails, your provider’s own sign-in log usually says why (a scope it doesn’t allow, the wrong client authentication, or a user who isn’t assigned to the app). SafeHanded shows the provider’s error code on the sign-in page.

SafeHanded uses the authorization code flow with PKCE, checks the ID token’s signature against your provider’s published keys, and accepts only asymmetric signatures (RS256, PS256, ES256 and their longer variants). When your provider rotates its keys, SafeHanded fetches the new ones automatically.

By default SafeHanded reads the email, name and groups claims. Change the claim names under Scopes and claims if your provider uses others (for example upn, or a namespaced name such as https://example.com/groups), and add a scope if your provider needs one to include groups. Group names are matched exactly, including capitals. The groups claim drives provision by group and group → role mapping, exactly as for the other providers.

On the Team plan and above, providers that support SCIM (Okta, JumpCloud, OneLogin and others) can create and disable members automatically. See Automatic provisioning (SCIM) for each provider’s steps.