SSO Setup: Microsoft Entra ID

Microsoft Entra ID (formerly Azure Active Directory) is the most common IdP for organizations already using Microsoft 365 or Azure. Setup takes ~15 minutes and you don't need an Azure subscription (Entra is free at the tier this requires).

Before you start

You need:

  • Tenant admin access in Microsoft Entra ID for the directory that contains the users you want to sign in. If you're not sure which directory that is, it's usually the one tied to your @yourcompany.com work account.
  • Admin access in JAMS IMES β€” only admins can configure integrations.
  • The JAMS IMES Redirect URI, shown on the /integrations/sso page. Have this tab open in another window before you start.

Tip: if your Azure account has multiple directories, double-check you're in the right one before creating the App Registration. The directory selector is in the top-right of the Azure Portal under your user avatar β†’ "Switch directory."

Step 1 β€” Create the App Registration

  1. Open the Azure Portal.
  2. In the top search bar, type "Entra" and click Microsoft Entra ID.
  3. In the left sidebar, click App registrations β†’ + New registration.
  4. Fill in:
FieldValue
NameJAMS IMES SSO (or whatever β€” only visible to Entra admins)
Supported account typesAccounts in this organizational directory only (Single tenant). Don't pick multi-tenant unless you understand the implications.
Redirect URIPlatform: Web. URI: paste the value from JAMS IMES's /integrations/sso page (looks like https://notiphone-.../auth/sso/callback).
  1. Click Register. You land on the App Registration overview page.

Step 2 β€” Capture the IDs

The overview page shows two values you need:

  • Application (client) ID β€” looks like aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee. This becomes the Client ID in JAMS IMES.
  • Directory (tenant) ID β€” also a UUID. You'll use this to build the Issuer URL below.

Copy both somewhere temporary (password manager, scratch note). You won't be able to see the Client Secret value after the next step, so don't navigate away yet.

The Issuer URL you'll need in JAMS IMES is:

https://login.microsoftonline.com/<Directory-tenant-ID>/v2.0

The /v2.0 suffix matters β€” without it Entra serves the older v1 endpoint with different claim names that confuse JAMS IMES.

Step 3 β€” Create the Client Secret

  1. Left sidebar (still inside your App Registration) β†’ Certificates & secrets.
  2. Click + New client secret.
  3. Fill in:
    • Description: include a date for rotation tracking. Example: JAMS IMES backend 2026-05-15.
    • Expires: pick 24 months (longer is better; Azure forces an expiry). Set a calendar reminder for 30 days before it expires so you can rotate without an outage.
  4. Click Add.

⚠️ Critical: the Value column shows the secret only once. After you navigate away from this page, the value is permanently hidden β€” only the meta "Secret ID" stays visible (that's NOT the secret). Copy the Value immediately to a password manager or your scratch note.

If you close the page without copying: delete the secret and create a new one. There's no recovery path.

Step 4 β€” Verify API permissions

Left sidebar β†’ API permissions. You should see at minimum:

Microsoft Graph
  User.Read (Delegated) β€” Sign in and read user profile

This is added by default and is enough for OIDC. The openid, profile, and email scopes are included implicitly.

If you want to be explicit (recommended for production audits):

  1. Click + Add a permission β†’ Microsoft Graph β†’ Delegated permissions.
  2. Check: openid, profile, email, offline_access.
  3. Click Add permissions.
  4. Click Grant admin consent for [your tenant]. This skips the user consent prompt on first login.

Step 5 β€” (Skip unless needed) Token configuration

The Token configuration page should be blank β€” that's the right starting state. Entra v2.0 returns the standard OIDC claims (email, name, given_name, family_name) by default when you request openid profile email scopes. Nothing to configure here for most setups.

You'd only come back if a later test fails with sso_no_email_claim. In that case:

  1. Click + Add optional claim β†’ ID β†’ check email β†’ Add.
  2. Try the SSO sign-in again.

Step 6 β€” Configure JAMS IMES

Open JAMS IMES in another tab. Go to /integrations/sso.

Fill in the form:

FieldValue
Configuration nameMicrosoft Entra ID (this is what users see on the login button β€” pick something recognizable)
Issuer URLhttps://login.microsoftonline.com/<Directory-tenant-ID>/v2.0 (paste the directory ID from Step 2)
Client IDfrom Step 2 (the Application ID)
Client Secretfrom Step 3 (the Value you copied)
Scopesleave default: openid profile email
Email / First name / Last name claimleave defaults: email, given_name, family_name
Enforce SSOleave OFF for first test. Only flip on AFTER you've verified SSO works for at least one admin. Otherwise you can lock yourself out.

Click Save Configuration. If the save succeeds, the page reloads showing "Active SSO configuration" with the issuer, client ID, etc. visible.

Step 7 β€” Test the flow

  1. Open an incognito/private window (clean state, no leftover cookies).
  2. Navigate to https://<your-notiphone-frontend>/login.
  3. Type the email of an existing JAMS IMES User whose email matches a user in your Entra tenant.
  4. Click Continue.
  5. You should see a "Continue with Microsoft Entra ID" button (or whatever you named the config).
  6. Click it β†’ browser redirects to Microsoft's sign-in page.
  7. Sign in with your Entra credentials. First-time users may see a consent prompt ("JAMS IMES wants to sign you in and read your profile") β€” accept.
  8. You should land back at JAMS IMES's /sso-complete page briefly, then the dashboard.

If you land on the dashboard signed in as yourself, SSO is working. πŸŽ‰

Step 8 β€” (Optional) Turn on Enforce SSO

Once you've verified at least one admin can sign in via SSO:

  1. Open /integrations/sso β†’ Edit your config.
  2. Check the Enforce SSO checkbox.
  3. Save.

After this, password login is rejected for every user in your tenant. They MUST use the IdP button on /login. New invitees skip the password field on accept and are sent straight to the IdP.

Safety note: before turning Enforce SSO on, make sure at least one admin can sign in via SSO. If everyone's Entra account is misconfigured and you also enforce SSO, nobody can get in. Turning Enforce SSO back off requires database access.

What can go wrong

Error code on /login?sso_error=What happenedFix
user_not_provisionedThe email Entra returned doesn't match any User in your JAMS IMES tenantInvite the user from Team Members first. Email casing doesn't matter; spelling does.
sso_idp_rejectedMicrosoft refused the code exchangeUsually a Client Secret typo. Re-paste it in JAMS IMES, or regenerate in Entra and update both sides.
sso_no_email_claimEntra didn't return an email in the ID tokenCommon with personal Microsoft accounts (Outlook/Hotmail) where the "email" isn't sourced from a real domain. Either use a work account, or go to Token configuration β†’ add email as an optional claim.
account_disabledThe User exists in JAMS IMES but is deactivatedReactivate in Team Members.
Browser shows AADSTS50011 ("Reply URL does not match")Redirect URI mismatch between Entra and JAMS IMESCheck both match EXACTLY, including https:// vs http://, trailing slashes, port numbers. Update Entra's Authentication β†’ Web β†’ Redirect URIs to match what JAMS IMES's /integrations/sso page shows.
Browser shows AADSTS70002 / "client secret expired"Your secret hit its expiry dateGenerate a new one in Entra (Certificates & secrets), update in JAMS IMES, save.

Rotation: when the Client Secret approaches expiry

About 30 days before expiry, generate a NEW Client Secret in Entra (don't delete the old one yet). In JAMS IMES, edit the SSO config and paste the new value. Save and immediately test sign-in with another user. Once confirmed, delete the OLD secret in Entra.

If you wait until the secret actually expires, every sign-in fails with sso_idp_rejected until you rotate. Set a calendar reminder.

What's next