Single Sign-On (SSO)

Single Sign-On (SSO) lets your team log in to JAMS IMES via your existing identity provider. No JAMS IMES-specific passwords to manage; user offboarding in your IdP automatically revokes JAMS IMES access.

JAMS IMES supports any OIDC-compliant identity provider β€” Microsoft Entra ID, Okta, Google Workspace, Auth0, OneLogin, Keycloak, AWS Cognito, Ping Identity, and many more. The setup is the same shape for all of them; only the IdP's portal looks different.

What you'll get

After setup:

  • Users hit /login, type their email, click Continue with [your IdP name]
  • They're redirected to your IdP, sign in there
  • They return to JAMS IMES already signed in β€” no password prompt

If you turn on Enforce SSO, JAMS IMES rejects password login entirely for everyone in your tenant. Useful for compliance ("all access goes through our IdP"). Optional β€” default is off.

Important constraints (v1)

JAMS IMES's SSO is intentionally simple in v1. A few constraints to know:

  • No JIT provisioning. Users must already be invited to JAMS IMES (see Inviting Users) before they can sign in via SSO. SSO bypasses the password step but doesn't auto-create accounts. This prevents anyone with an @yourcompany.com email from creating their own JAMS IMES account without your invite.
  • One IdP per tenant. Pick the one your team uses. Multi-IdP support per tenant is a future feature.
  • OIDC only. SAML support is planned but not in v1. If your IdP only supports SAML (rare for new accounts), let us know.
  • Email-based matching. JAMS IMES matches the email returned by your IdP to the User record in JAMS IMES. They must match exactly. If your IdP returns Kevin.Casey@Example.com but JAMS IMES has kevin.casey@example.com, the case-insensitive match handles it β€” but anything else (typos, alias, different domain) will fail.

The shape of every IdP setup

Doesn't matter which IdP you use β€” the steps are always the same:

  1. In your IdP, create an OIDC application (sometimes called "Web Application," "Regular Web App," etc.).
  2. In your IdP, set the Redirect URI to whatever JAMS IMES's /integrations/sso page shows you. Format is https://notiphone-.../auth/sso/callback.
  3. In your IdP, copy three things: the Issuer URL (often called Discovery URL, OpenID Connect metadata URL β€” strip any /.well-known/openid-configuration suffix), the Client ID, and a Client Secret that you generate.
  4. In JAMS IMES, open /integrations/sso and paste those three values into the form.
  5. Save. Test by logging out and back in.
  6. (Optional) Once you've confirmed SSO works for at least one admin, flip Enforce SSO on.

That's it. The differences between IdPs come down to where in their UI those four pieces of info live.

Detailed walkthroughs

If you use…See this guide
Microsoft Entra ID (formerly Azure AD)Entra ID setup
OktaOkta setup
Google WorkspaceGoogle Workspace setup
Auth0Auth0 setup
Anything else OIDC-compliantUse the Entra ID guide as a template β€” the JAMS IMES-side steps are identical; only the IdP-side UI differs.

After setup

  • The button label on /login uses the "Configuration name" you typed when saving the SSO config. So name it something users will recognize (e.g. "Microsoft Entra ID", not "config-1").
  • Existing users with passwords keep them. Turning on SSO doesn't delete anyone's password β€” they just stop using it. If you flip Enforce SSO off later, password login resumes for everyone.
  • Inviting users into an SSO-enforced tenant: invite as normal. JAMS IMES detects the enforced-SSO config and skips the password step on the invite accept page, sending the new user straight to your IdP after they fill in their name.

Troubleshooting

If SSO sign-in fails, the redirect from your IdP back to JAMS IMES includes a query param ?sso_error=<code> on /login. The error codes:

ErrorWhat happenedFix
user_not_provisionedThe email your IdP returned doesn't match any JAMS IMES User in this tenantInvite the user from Team Members, then retry SSO
account_disabledThe user exists but is deactivatedReactivate in Team Members
sso_idp_rejectedYour IdP refused the code exchange β€” usually a bad Client SecretRe-save the Client Secret in /integrations/sso; generate a new one in your IdP if the old one was rotated
sso_no_email_claimYour IdP didn't return an email in the ID tokenAdd email as a scope or optional claim in your IdP config
sso_state_invalidThe SSO session expired (5 min window)Just retry β€” usually means the user left the IdP page open for too long

Security notes

  • Your Client Secret is encrypted at rest in JAMS IMES β€” AES-256-GCM with a key in Azure Key Vault. Never appears in API responses or logs.
  • The OAuth state is signed with JAMS IMES's JWT secret and includes PKCE, so even if an attacker observed the redirect URL they couldn't replay it.
  • Session JWTs are stored client-side in localStorage, same as password login. Same 8-hour expiry. Logout clears them.

What's next

Pick your IdP from the table above and follow the walkthrough. They're each about 10–15 minutes including the IdP-side configuration.