Single Sign-On (SSO)¶
Connect GxPSign to your organization's identity provider (IdP) so users sign in with their existing corporate credentials.
GxPSign supports two protocols:
| Protocol | Best for |
|---|---|
| OpenID Connect (OIDC) | Recommended. Simpler setup, endpoint auto-discovery, works with every major IdP. |
| SAML 2.0 | Use when your IdP or IT policy mandates SAML. |
Admin Access Required
SSO configuration requires Organization Owner or Organization Admin permissions. Go to Settings > SSO (/app/sso/).
Before You Start¶
You need three things in place:
- Your email domain is set on the organization. Go to Settings > Organization > Edit and fill in the Domain field (e.g.
acme.com). This is what routes your users to SSO at login — without it, the SSO button never appears. - Admin access to your identity provider, so you can create an application and copy its client credentials.
- Your users are invited to GxPSign first. See the warning below.
SSO does not auto-onboard users
A matching email domain is not enough to get someone in. The first time a person signs in via SSO, GxPSign only creates their account if they are already a member of your organization or have a pending invitation. Everyone else is turned away with:
Your account is not authorized for SSO to this organization. Ask an administrator to send you an invitation.
Invite users from Settings > Users > Invite before pointing them at SSO. See Managing Users.
Role on first SSO login
A user who joins via SSO is created with the User role, regardless of the role you selected on their invitation. If you invited someone as an Organization Admin, promote them under Settings > Users after their first sign-in.
How Your Users Sign In¶
Your users don't need a special link — the normal login page routes them automatically:
- The user enters their email address at Sign In.
- When they tab out of the field, GxPSign matches the email's domain against your organization's Domain and, if SSO is enabled, swaps in a Sign in with your provider name button.
- Clicking it sends them to your IdP, and your IdP returns them to GxPSign, signed in.
If you have enforced SSO, a user who tries an email + password sign-in instead is stopped with "Your organization requires Single Sign-On. Please use the SSO login," and the SSO button is shown to them.
The SSO Login URL¶
Once SSO is enabled, the SSO page also shows an SSO Login URL you can copy and share — from your intranet, a bookmark, or a welcome email:
Opening it skips the email step and goes straight to your IdP. It's a convenience, not a requirement: the email-domain routing above works whether or not anyone uses this link.
Subdomains are cosmetic
Your your-slug.gxpsign.app subdomain does not affect sign-in routing. SSO is matched on the email domain, from the main login page.
Setting Up OIDC¶
Step 1 — Copy your Redirect URI¶
Go to Settings > SSO. Select OpenID Connect (OIDC) as the active protocol. In the Configure SSO Provider panel, an amber box shows Configure this Redirect URI in your Identity Provider. Copy that value. It looks like:
Your IdP will reject the login if this does not match exactly — including the trailing slash and https://.
Step 2 — Create the application in your IdP¶
Create a web application (also called a confidential client or regular web app — not a single-page app, not a native/mobile app) and paste the Redirect URI from Step 1 into it. See Provider-Specific Setup below for the exact menu path for your IdP.
Collect three values:
- The Issuer URL
- The Client ID
- The Client Secret
Step 3 — Fill in the GxPSign form¶
Back on Settings > SSO:
| Field | What to enter |
|---|---|
| Name | A label your users will see on the login button, e.g. Acme Okta. This appears as "Sign in with Acme Okta." |
| Oidc issuer | Your IdP's issuer URL. Leave the four endpoint fields blank and let GxPSign discover them — see below. |
| Oidc client id | Client ID from your IdP. |
| Oidc client secret | Client Secret from your IdP. Stored encrypted at rest. |
| Oidc scopes | Leave as openid email profile unless you have a reason to change it. |
| Oidc authorization endpoint | Leave blank. |
| Oidc token endpoint | Leave blank. |
| Oidc userinfo endpoint | Leave blank. |
| Oidc jwks uri | Leave blank. |
Click Save.
No trailing slash on the issuer
GxPSign builds the discovery URL by appending /.well-known/openid-configuration to whatever you type. If you paste https://acme.auth0.com/ you get a double slash — https://acme.auth0.com//.well-known/... — which some providers reject. Drop the trailing slash, even where your IdP's own documentation shows one (Auth0 and JumpCloud both do).
Only Name and Oidc scopes are enforced by the form
The form will happily save with the Client ID, Client Secret, or Issuer missing. It will simply fail at Test Connection or at login. Use Test Connection as your real check that the configuration is complete.
Step 4 — Test the connection¶
Click Test Connection. This fetches your issuer's discovery document and verifies GxPSign can reach your IdP.
What the test does and doesn't cover
Test Connection checks that your issuer is reachable and its endpoints resolve. It does not perform a full login round-trip, so it will not catch a wrong Client Secret or a mismatched Redirect URI. Always finish with a real sign-in from a private browser window.
Step 5 — Enable SSO¶
The Enable SSO button stays locked until the connection has tested successfully. Once it passes, click Enable SSO. The login page will now offer the SSO button to anyone whose email matches your organization's domain.
Sign in yourself, from a private/incognito window, before telling your users about it.
Step 6 — Enforce SSO (optional)¶
Click Enforce SSO to disable password sign-in for your organization. Users must then authenticate through your IdP.
Do not enforce until SSO is proven
Enforcing SSO with a broken configuration locks your whole organization out. Complete a real end-to-end sign-in first, and keep at least one Organization Owner able to sign in — an individual member's authentication method can be set back to local under Settings > Users if you need a break-glass account.
Using the Well-Known Endpoint¶
OIDC providers publish a discovery document — a machine-readable JSON file listing every URL and capability of the provider. It always lives at the issuer URL plus /.well-known/openid-configuration:
This is why you can leave the four endpoint fields blank. Give GxPSign the Oidc issuer and it reads the rest from that document at login time — so your configuration also keeps working if your IdP moves an endpoint later.
Checking it yourself¶
If setup misbehaves, fetch the document directly. Anything the browser can reach, you can check:
You should get JSON containing at minimum:
{
"issuer": "https://login.microsoftonline.com/<tenant-id>/v2.0",
"authorization_endpoint": "...",
"token_endpoint": "...",
"userinfo_endpoint": "...",
"jwks_uri": "..."
}
Two things to check:
- You get JSON, not a 404 or an HTML login page. A 404 almost always means the issuer URL is wrong — a missing path segment, an extra trailing slash, or the wrong tenant/realm ID.
- The
issuervalue in the JSON matches what you typed, character for character. If your IdP reports a different issuer than the one you configured, token validation will fail at login. Copy the value from the document into the Oidc issuer field.
Filling the endpoints manually¶
Discovery is the recommended path. Fill the endpoints in by hand only if your IdP does not publish a discovery document, or it sits behind a network path GxPSign cannot reach. Copy each value from the JSON into its matching field:
| Discovery document key | GxPSign field |
|---|---|
authorization_endpoint | Oidc authorization endpoint |
token_endpoint | Oidc token endpoint |
userinfo_endpoint | Oidc userinfo endpoint |
jwks_uri | Oidc jwks uri |
Manual endpoints override discovery. If you fill them in, you own keeping them current.
Provider-Specific Setup¶
Replace the placeholders in angle brackets with your own values. In every case, the Redirect URI you paste is the one from Step 1.
Formerly Azure AD.
| Issuer | https://login.microsoftonline.com/<tenant-id>/v2.0 |
| Create the app | entra.microsoft.com > Entra ID > App registrations > New registration |
| Redirect URI | On registration, or later under Authentication > Add a platform > Web |
| Client ID | Overview page > Application (client) ID |
| Client Secret | Certificates & secrets > Client secrets > New client secret |
<tenant-id>is your Directory (tenant) ID from the Overview page. Use the specific GUID — notcommon— so only your own directory can sign in.- Copy the secret Value, not the Secret ID. The Value is only shown once.
Client secrets expire
Entra client secrets last a maximum of 24 months and cannot be extended — you must issue a new one. When it expires, SSO stops for your whole organization. Set a calendar reminder ahead of the expiry date and paste the new secret into Oidc client secret.
| Issuer | https://accounts.google.com |
| Create the app | Google Cloud Console > APIs & Services > Credentials > Create Credentials > OAuth client ID > Web application |
| Redirect URI | Field named Authorized redirect URIs |
| Client ID / Secret | Shown on creation |
- Configure the OAuth consent screen first, or client creation is blocked. Set the user type to Internal so only your Workspace users can sign in.
- The Client Secret is displayed once at creation — save it immediately. Afterwards the Console shows only the last four characters.
- Changes to authorized redirect URIs can take a few minutes to propagate. If your first attempt fails with a redirect URI mismatch, wait and retry before re-editing.
| Issuer | https://<your-okta-domain> (org authorization server) or https://<your-okta-domain>/oauth2/default (default custom authorization server) |
| Create the app | Admin Console > Applications > Applications > Create App Integration > OIDC – OpenID Connect > Web Application |
| Redirect URI | Field named Sign-in redirect URIs |
| Client ID / Secret | General tab > Client Credentials |
- Either issuer works. Confirm which one you have by opening its
/.well-known/openid-configurationand reading theissuervalue back. - If you use
/oauth2/default, it needs an Access Policy attached — Okta does not add one automatically, and without it logins fail even though discovery succeeds. - Assign the application to the users or groups who should have access, under the Assignments tab.
| Issuer | https://<your-tenant>.auth0.com — drop the trailing slash Auth0's docs show |
| Create the app | Dashboard > Applications > Create Application > Regular Web Application |
| Redirect URI | Field named Allowed Callback URLs |
| Client ID / Secret | Settings tab > Basic Information (click Reveal Client Secret) |
- Signing algorithm must be RS256, which is the default. HS256 is not appropriate here.
- Never use a wildcard in Allowed Callback URLs — paste the exact Redirect URI.
| Issuer | https://auth.pingone.com/<environment-id>/as |
| Create the app | Admin Console > Applications > Applications > + > OIDC Web App |
| Redirect URI | Field named Redirect URIs, on the Configuration tab |
| Client ID / Secret | Configuration tab > General |
- Regional tenants use a different host —
auth.pingone.eu,auth.pingone.ca,auth.pingone.asia. Use the one matching your environment. - Set Response type to
Codeand Grant type toAuthorization Code. - PingFederate (on-premises) is a different product with its own console and issuer scheme. Read its issuer from your deployment's discovery document.
| Issuer | https://oauth.id.jumpcloud.com — drop the trailing slash JumpCloud's docs show |
| Create the app | Admin Portal > SSO Applications > Add New Application > Custom Application > Configure SSO with OIDC |
| Redirect URI | Field named Redirect URIs |
| Client ID / Secret | Shown once in a popup after you activate the connector |
- The Client ID and Secret cannot be retrieved later — only regenerated. Save them before closing the popup.
- Set Client Authentication Type to a client-secret method (
Client Secret BasicorClient Secret Post), not Public/PKCE. - EU and IN regions use different subdomains.
| Issuer | https://<subdomain>.onelogin.com/oidc/2 |
| Create the app | Admin > Applications > Add App > search OpenId Connect (OIDC) |
| Redirect URI | Field named Redirect URI's, on the Configuration tab |
| Client ID / Secret | SSO tab (click Show client secret) |
- OneLogin has changed its issuer format historically. Don't assume — the SSO tab shows your tenant's actual Issuer URL. Use that value.
| Issuer | https://<your-keycloak-host>/realms/<realm-name> |
| Create the app | Admin Console > select realm > Clients > Create client, type OpenID Connect |
| Redirect URI | Field named Valid Redirect URIs |
| Client Secret | Credentials tab |
- On the Capability config step, turn Client authentication to On. This makes the client confidential — the Credentials tab only appears once you do.
- Turn Direct access grants off; it is on by default and is not needed for this flow.
- Keycloak must be reachable from GxPSign at the same hostname it advertises in its discovery document. A misconfigured
--hostnameis the usual cause of an issuer mismatch.
Troubleshooting¶
| Symptom | Likely cause |
|---|---|
| No SSO button appears at login | Organization Domain not set, doesn't match the user's email domain, or SSO isn't enabled. |
| Enable SSO is greyed out | The connection hasn't passed Test Connection yet. |
| Test Connection fails | Issuer URL wrong. Open <issuer>/.well-known/openid-configuration in a browser — if it 404s, the issuer is wrong; check for a trailing slash. |
| IdP shows "redirect URI mismatch" | The URI in your IdP doesn't exactly match the one on the SSO page. Check the trailing slash, https://, and the org slug. |
| Login fails after the IdP accepts credentials | Wrong or expired Client Secret, or the issuer in the discovery document differs from what you configured. |
| "Your account is not authorized for SSO to this organization" | The user has no membership and no pending invitation. Invite them first. |
| "Your organization requires Single Sign-On" on password login | Expected when SSO is enforced. Use the SSO button. |
| User signed in via SSO but has the wrong role | Roles aren't taken from the invitation on SSO sign-up. Set the role under Settings > Users. |
| Email missing from the IdP response | The email claim is required. Confirm Oidc scopes includes email and your IdP releases it. |
Changing the org slug breaks SSO
Your Redirect URI contains your organization slug. If you change the slug under Settings > Organization, update the Redirect URI in your IdP to match, or SSO logins will fail.
What GxPSign Reads From Your IdP¶
With the default openid email profile scopes:
| Claim | Used for |
|---|---|
email | Required. The user's account identity. Login fails without it. |
given_name / first_name | First name |
family_name / last_name | Last name |
sub | Stable link between the GxPSign user and your IdP account |
No group or role mapping
GxPSign does not read groups, roles, or custom claims from your IdP. Permissions are managed entirely in GxPSign under Settings > Users. Adding a groups scope or claim in your IdP has no effect here.
SAML 2.0¶
Use SAML only where OIDC isn't an option — it has no discovery equivalent, so every value is entered by hand.
On Settings > SSO, select SAML 2.0 as the active protocol. The info box gives you two URLs for your IdP:
| GxPSign shows | Paste into your IdP as |
|---|---|
| ACS URL (Assertion Consumer Service) | Assertion Consumer Service / Reply URL |
| SP Metadata URL | Service Provider metadata, and the SP Entity ID |
Then fill in, from your IdP:
| Field | What to enter |
|---|---|
| Name | Login button label |
| Saml entity id | Your IdP's Entity ID / Issuer |
| Saml sso url | Your IdP's SSO / SAML endpoint |
| Saml slo url | Single Logout URL (optional) |
| Saml x509 cert | Your IdP's signing certificate, PEM format. Encrypted at rest. |
| Saml attribute mapping | JSON, only if your IdP's attribute names differ from the defaults |
GxPSign requests the NameID format urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress and reads the email, firstName, and lastName attributes. If your IdP emits different attribute names, map them:
{
"email": "urn:oid:0.9.2342.19200300.100.1.3",
"firstName": "urn:oid:2.5.4.42",
"lastName": "urn:oid:2.5.4.4"
}
There is no metadata import — GxPSign cannot pull your IdP's settings from a metadata URL. Test and enable exactly as with OIDC.
Certificate rotation
When your IdP rotates its signing certificate, paste the new one into Saml x509 cert. SSO breaks the moment the old certificate is retired.
Related¶
- Managing Users — invite users before pointing them at SSO
- Organization Setup — set your email domain
- Require passkey to sign — SSO step-up at signing time