SSO & SCIM Setup Microsoft Entra ID
End-to-end setup for signing in to AgentWatch with Microsoft Entra ID, and for provisioning users and groups from Entra into AgentWatch. There are two ways to do it with Entra; pick ONE:
| Method 1 — OIDC (Part A) | Method 2 — SAML + SCIM (Part B) | |
|---|---|---|
| Entra object | App registration | Enterprise application (non-gallery) |
| Sign-in protocol | OpenID Connect | SAML 2.0 |
| User provisioning (SCIM) | Needs a second, separate Enterprise application (A.9) | Same app — Provisioning tab |
| Choose when | You want sign-in only, or your org standardises on OIDC | You want sign-in AND provisioning managed in one Entra app, or policy mandates SAML |
Also covered:
- Part C — Verification + Troubleshooting (Entra error codes → fix)
Other identity providers (Okta, Auth0, Google Workspace, Ping) are covered in the AgentWatch SAML SSO Setup guide and on docs.iterate.ai.
Prerequisites
Section titled “Prerequisites”| Side | Requirement |
|---|---|
| Microsoft Entra | Application Administrator, Cloud Application Administrator, or Global Administrator role |
| AgentWatch | Company Admin or Super Admin role |
| Network | AgentWatch host reachable from Microsoft public IPs (SCIM push + OIDC discovery + SAML POST) |
| TLS | AgentWatch served over HTTPS with a trusted cert (SCIM and OIDC reject self-signed) |
| Host URL | e.g. https://agentwatch.example.com — used in every callback, ACS and SCIM URL below |
Part A — Method 1: OIDC via App registration (sign-in)
Section titled “Part A — Method 1: OIDC via App registration (sign-in)”Users enter their work email on the AgentWatch login page and are sent to Microsoft to authenticate. Users are created in AgentWatch on first sign-in (Auto-create users). For up-front provisioning and deprovisioning, add A.9.
A.1 — Register the OIDC application in Entra
Section titled “A.1 — Register the OIDC application in Entra”- Sign in to the Microsoft Entra admin center: https://entra.microsoft.com
- Left nav → Entra ID → App registrations → + New registration
- Fill:
- Name:
AgentWatch SSO - Supported account types: Accounts in this organizational directory only (Single tenant)
- Redirect URI: leave blank for now — added in A.8 once AgentWatch shows it
- Name:
- Click Register
Copy from the Overview page:
| Entra label | Use later as |
|---|---|
| Application (client) ID | AgentWatch Client ID |
| Directory (tenant) ID | Builds the AgentWatch Issuer URL: https://login.microsoftonline.com/<TENANT_ID>/v2.0 |
A.2 — Create a Client Secret
Section titled “A.2 — Create a Client Secret”- Inside the app → Certificates & secrets → + New client secret
- Name
agentwatch-prod, expiry 24 months → Add - Copy the “Value” column immediately — it is shown once. The “Secret ID” column is NOT the secret.
A.3 — Grant API permissions
Section titled “A.3 — Grant API permissions”- API permissions → + Add a permission → Microsoft Graph → Delegated permissions
- Tick
openid,profile,email,User.Read - (Optional, for group sync) also
GroupMember.Read.All - Add permissions → Grant admin consent for <tenant>
A.4 — Emit the groups claim (optional — only for group → team mapping)
Section titled “A.4 — Emit the groups claim (optional — only for group → team mapping)”- Token configuration → + Add groups claim
- Select Security groups (or Groups assigned to the application)
- ID token format: Group ID (recommended) or sAMAccountName (on-prem-synced names only)
- Save
⚠ With Group ID, Entra sends group object IDs (GUIDs), not display names. A mapping typed as a display name matches nothing and reports nothing. After one test sign-in, read the exact values Entra sent from
GET /admin/sso/observed-groups?providerId=<id>and map those.
A.5 — Start the AgentWatch wizard
Section titled “A.5 — Start the AgentWatch wizard”AgentWatch → Settings → Single Sign-On → + Add Authentication → pick the Microsoft tile (OIDC) → Next ›.
A.6 — Fill the Connection fields
Section titled “A.6 — Fill the Connection fields”| AgentWatch field | Value |
|---|---|
| Display Name | e.g. Contoso Entra — the label on the sign-in button |
| Issuer URL | https://login.microsoftonline.com/<TENANT_ID>/v2.0 (no trailing slash) |
| Client ID | Application (client) ID from A.1 |
| Client Secret | Secret Value from A.2 |
| Scopes | openid profile email |
| Callback URL | (read-only — copy it; registered in Entra in A.8) |
| Email domain restriction | (optional) e.g. contoso.com |
| Group Claim Key | groups |
| Enabled / Auto-create users | ☑ / ☑ |
Next ›.
A.7 — Test, Groups, Review
Section titled “A.7 — Test, Groups, Review”The wizard fetches <Issuer URL>/.well-known/openid-configuration; a green check means the Issuer URL is right.
| Group sync mode | Behavior |
|---|---|
| Off | No team mapping — users join the org default team |
| Auto | Every IdP group becomes its own AgentWatch team on first sign-in |
| Manual | Only the Entra group object IDs you map become teams + roles (recommended for production) |
Tick Enable this provider for sign-in immediately → Save & Finish.
A.8 — Register the Callback URL in Entra
Section titled “A.8 — Register the Callback URL in Entra”- Entra → your app registration → Authentication → + Add a platform → Web
- Paste the AgentWatch Callback URL from A.6 (e.g.
https://agentwatch.example.com/api/auth/sso/callback) - Under Implicit grant and hybrid flows tick ID tokens
- Configure → Save
Test in an incognito window: AgentWatch login → enter your work email → Continue → Microsoft sign-in → back in the AgentWatch dashboard.
A.9 — (Optional) Add SCIM provisioning to an OIDC setup
Section titled “A.9 — (Optional) Add SCIM provisioning to an OIDC setup”Provisioning cannot be switched on for the enterprise application that an App registration creates — Entra shows “Out of the box automatic provisioning to <app> is not supported today” and greys out Get started. Create a separate non-gallery Enterprise application just for provisioning:
- Do B.1 (create the non-gallery app), naming it
AgentWatch SCIM. Skip B.2–B.8 — sign-in stays on the OIDC app. - Do B.9–B.14 on that app.
- Assign the same users/groups to both apps, or the two will disagree about who exists.
Part B — Method 2: SAML sign-in + SCIM provisioning in ONE Enterprise application
Section titled “Part B — Method 2: SAML sign-in + SCIM provisioning in ONE Enterprise application”One non-gallery Enterprise application does both jobs: its Single sign-on tab handles SAML sign-in, its Provisioning tab pushes users and groups over SCIM. Assignments on Users and groups control both.
B.1 — Create the non-gallery Enterprise application
Section titled “B.1 — Create the non-gallery Enterprise application”- Entra admin center → Enterprise applications → All applications → + New application
- + Create your own application
- Name:
AgentWatch(any name; examples below useAgentWatch SCIM) - Select Integrate any other application you don’t find in the gallery (Non-gallery)
- Create — wait ~30 s for the Overview page
B.2 — Collect the Entra (IdP) SAML values
Section titled “B.2 — Collect the Entra (IdP) SAML values”- In the app → Single sign-on → select SAML
- Scroll to section 3 — SAML Certificates → Federation Metadata XML → Download (or Certificate (Base64) → Download, if you prefer to paste fields by hand)
- Section 4 — Set up <app> lists:
| Entra label | Looks like | AgentWatch field (B.3) |
|---|---|---|
| Login URL | https://login.microsoftonline.com/<TENANT_ID>/saml2 |
SAML Entry Point (SSO URL) |
| Microsoft Entra Identifier | https://sts.windows.net/<TENANT_ID>/ |
SAML Issuer (Entity ID) |
| Certificate (Base64) | .cer file |
X.509 Certificate (PEM) |
⚠ SAML Issuer takes the Entra identifier (
sts.windows.net/...), NOT the AgentWatch metadata URL. The AgentWatch URLs go the other way — into Entra, in B.4.
B.3 — Create the SAML provider in AgentWatch
Section titled “B.3 — Create the SAML provider in AgentWatch”- AgentWatch → Settings → Single Sign-On → + Add Authentication → pick the SAML tile → Next ›
- Either upload the Federation Metadata XML (“Or upload IdP metadata XML to auto-fill…”) — this fills Entry Point, Issuer and Certificate — or paste the three values from B.2. When pasting the certificate, include the
-----BEGIN CERTIFICATE-----/-----END CERTIFICATE-----lines. - Remaining fields:
| AgentWatch field | Value |
|---|---|
| Display Name | e.g. Contoso Entra SAML |
| Group Claim Key | http://schemas.microsoft.com/ws/2008/06/identity/claims/groups (the default) |
| Email domain restriction | (optional) |
| Enabled / Auto-create users | ☑ / ☑ |
- Next › — this saves a draft and gives the provider its ID. The right-hand
column now shows the two values Entra needs:
- ACS URL —
https://<host>/api/auth/saml/callback/<provider-id> - SP Entity ID (Identifier) —
https://<host>/api/auth/saml/metadata/<provider-id>
- ACS URL —
⚠ Both URLs embed the provider ID. Every new provider gets a new ID, so re-running the wizard or deleting and recreating the provider changes both URLs. Keep exactly ONE Entra SAML provider in AgentWatch, and re-copy the URLs into Entra whenever you recreate it — otherwise sign-in fails with
AADSTS700016(see C.3).
B.4 — Basic SAML Configuration in Entra
Section titled “B.4 — Basic SAML Configuration in Entra”Entra → the app → Single sign-on → section 1 — Basic SAML Configuration → Edit:
| Entra field | Value |
|---|---|
| Identifier (Entity ID) | AgentWatch SP Entity ID from B.3 |
| Reply URL (Assertion Consumer Service URL) | AgentWatch ACS URL from B.3 |
| Sign on URL / Relay State / Logout Url | leave empty |
Save. Update both fields together — the provider ID in them must be the same.
B.5 — Attributes & Claims
Section titled “B.5 — Attributes & Claims”Entra’s defaults work unchanged:
| Claim | Source | Used by AgentWatch as |
|---|---|---|
emailaddress |
user.mail |
the user’s email (first choice) |
| Unique User Identifier (NameID) | user.userprincipalname |
the email when mail is empty |
givenname / name |
user.givenname / user.userprincipalname |
display name |
(Optional, for group → team mapping) Edit → + Add a group claim →
Groups assigned to the application (or Security groups) → source
attribute Group ID → Save. As in A.4, these arrive as object IDs —
read them from GET /admin/sso/observed-groups?providerId=<id> before mapping.
B.6 — Signing option
Section titled “B.6 — Signing option”Section 3 — SAML Certificates → Edit:
- Signing Option: the default Sign SAML assertion works. Sign SAML response and assertion also works.
- Signing Algorithm: SHA-256.
If sign-in lands on
/login?sso_error=Invalid document signature, your AgentWatch build predates the fix that accepts assertion-only signing — set Sign SAML response and assertion here, or upgrade. If that does not clear it, the certificate stored in AgentWatch is not this app’s: re-download Certificate (Base64) and paste it into the provider (compare the Thumbprint shown in Entra).
B.7 — Assign users and groups
Section titled “B.7 — Assign users and groups”The app → Users and groups → + Add user/group → pick users and/or security groups → role User → Assign.
This one list governs BOTH halves: only assigned users can sign in (others get
AADSTS50105), and only assigned users/groups are provisioned in B.9–B.14.
B.8 — Finish the wizard and test sign-in
Section titled “B.8 — Finish the wizard and test sign-in”- Back in the AgentWatch wizard → Next › → choose the group sync mode (table in A.7) → Save & Finish with Enable this provider for sign-in immediately ticked.
- Incognito window → AgentWatch login → enter your work email → Continue → Microsoft sign-in → you land in the AgentWatch dashboard.
Test from the AgentWatch login page. Entra’s Test this application button starts an IdP-initiated sign-in, which is not the flow verified here.
B.9 — Generate a SCIM token in AgentWatch
Section titled “B.9 — Generate a SCIM token in AgentWatch”AgentWatch → Settings → User & Group Sync:
- Copy the SCIM Base URL —
https://<host>/scim/v2/<tenant-uuid> - + Generate Token → name it (e.g.
Entra) → Generate - Copy the token now (it starts with
scim_). It is shown once; if lost, revoke it and generate another.
B.10 — Pick the Group Sync behavior
Section titled “B.10 — Pick the Group Sync behavior”Same page → Group Sync Behavior:
| Mode | Behavior |
|---|---|
| Off | Ignore SCIM group pushes — users still provision, no team membership |
| Auto | Every Entra group pushed via SCIM becomes its own AgentWatch team |
| Mapped | Only pre-defined Entra group → AgentWatch team mappings take effect |
Pick a Group name parse rule (raw, or Strip "CN=" prefix… for DN-style names) and a Default org role for new users (Viewer recommended) → Save.
SCIM pushes the group’s display name (
displayName → displayName), unlike the SAML/OIDCgroupsclaim, which carries object IDs.
B.11 — Connect Entra provisioning
Section titled “B.11 — Connect Entra provisioning”Entra → the same app → Provisioning → Get started (or Connectivity):
| Entra field | Value |
|---|---|
| Provisioning Mode | Automatic |
| Authentication method | Bearer authentication |
| Tenant URL | SCIM Base URL from B.9 — no trailing slash |
| Secret Token | the scim_… token from B.9 |
Test Connection — wait for “The supplied credentials are authorized to enable provisioning” → Save.
B.12 — Mappings
Section titled “B.12 — Mappings”Expand Mappings:
| Mapping | Toggle | Attribute pairs (Entra defaults — leave as is) |
|---|---|---|
| Provision Microsoft Entra ID Users | On | userPrincipalName → userName, displayName → displayName, mail → emails[type eq "work"].value, accountEnabled → active |
| Provision Microsoft Entra ID Groups | On if syncing teams | displayName → displayName, members → members |
AgentWatch accepts the Entra defaults, including externalId → mailNickname; no mapping edits are needed.
B.13 — Scope and start
Section titled “B.13 — Scope and start”- Settings → Scope → Sync only assigned users and groups (the B.7 list)
- Provisioning Status → On → Save
The first cycle takes ~10–40 minutes; later cycles run about every 40 minutes. Provision on demand (top of the Provisioning page) pushes a single user immediately — useful for a first check.
B.14 — Verify provisioning
Section titled “B.14 — Verify provisioning”- Entra → Provisioning logs — one success row per user/group
- AgentWatch → Settings → User & Group Sync — Provisioned users and Groups synced climb; the token row’s Last used updates
- AgentWatch → Employee Management — provisioned users appear (
ssoStatus = provisioned); Team Management reflects the group sync mode
Part C — Verification & Troubleshooting
Section titled “Part C — Verification & Troubleshooting”C.1 — End-to-end smoke test
Section titled “C.1 — End-to-end smoke test”- Incognito → AgentWatch login → work email → Continue → Microsoft sign-in → dashboard
- Employee Management → user present,
ssoStatus = active - Team Management → teams reflect Entra groups (per the sync mode)
- (SCIM) Disable the user in Entra → wait one provisioning cycle (or Provision on demand) → user becomes
disabledin AgentWatch
C.2 — OIDC troubleshooting (Method 1)
Section titled “C.2 — OIDC troubleshooting (Method 1)”| Symptom | Likely cause | Fix |
|---|---|---|
| Test fails: “discovery endpoint unreachable” | Issuer URL typo | https://login.microsoftonline.com/<TENANT_ID>/v2.0, no trailing slash |
AADSTS50011: Reply URL mismatch |
Callback URL not registered | A.8 — paste the exact AgentWatch Callback URL under Web |
AADSTS65001: Admin consent required |
Permissions not consented | A.3 — Grant admin consent |
invalid_client |
Client Secret expired or wrong (Secret ID pasted instead of Value) | New secret in A.2, paste the Value |
| “domain not allowed” | Email domain restriction mismatch | Remove it, or add the user’s domain (comma-separated) |
| Signed in, no team | A.4 skipped; mapping typed as a group NAME; or user in >150 groups (overage) | Re-do A.4; map the object IDs from /admin/sso/observed-groups |
| “✗ Failed to parse JSON” on Review | Discovery returned non-JSON (proxy/captive portal) | curl <Issuer URL>/.well-known/openid-configuration from the AgentWatch host |
C.3 — SAML troubleshooting (Method 2)
Section titled “C.3 — SAML troubleshooting (Method 2)”| Symptom | Likely cause | Fix |
|---|---|---|
AADSTS700016: Application with identifier '…/api/auth/saml/metadata/<id>' was not found |
Entra’s Identifier holds a DIFFERENT provider ID than the one AgentWatch sent — the provider was recreated, or two SAML providers exist | Compare the <id> in the error with B.4’s Identifier. Update Identifier AND Reply URL to the current provider (B.3), or delete the extra provider |
AADSTS50011 (reply URL mismatch) |
Identifier updated, Reply URL not | B.4 — both fields must carry the same provider ID |
AADSTS50105 (user not assigned) |
User/group not on the app | B.7 |
/login?sso_error=Invalid document signature |
Build predates assertion-only signing, or wrong certificate | B.6 — set Sign SAML response and assertion; re-paste this app’s Certificate (Base64) |
sso_error=no_email_in_token |
Neither emailaddress nor a UPN-shaped NameID in the assertion |
B.5 — restore the default claims |
| Sign-in succeeds at Microsoft, then the AgentWatch login page reappears | Older builds redirected to /admin/sso-callback, which the path-prefix router (ENABLE_PATH_PREFIX_ROUTING=true) 301s to /login, dropping the token |
Upgrade to a build with the SAML landing fix (redirects to /sso-callback.html) |
| Signed in, no team | Group claim missing, or mapping typed as a group NAME | B.5 group claim; map the object IDs from /admin/sso/observed-groups |
| Wizard shows no ACS / SP Entity ID | Draft not saved yet | Fill the IdP fields and click Next › (B.3 step 4) |
To see exactly what AgentWatch expects for a provider, open
https://<host>/api/auth/saml/metadata/<provider-id> — its entityID and
AssertionConsumerService Location are the two values for B.4.
C.4 — SCIM troubleshooting
Section titled “C.4 — SCIM troubleshooting”| Symptom | Likely cause | Fix |
|---|---|---|
| Test Connection 401 | Wrong or revoked token | New token in B.9 |
| Test Connection 404 | Tenant URL typo, wrong tenant UUID, or trailing slash | Copy the SCIM Base URL exactly |
| Test Connection timeout | Host unreachable from Microsoft, or untrusted TLS cert | Open HTTPS to Microsoft IPs; use a trusted cert |
| Get started greyed out, “automatic provisioning … not supported” | Provisioning attempted on an App-registration’s enterprise app | Use a non-gallery Enterprise app (B.1 / A.9) |
| Provisioning logs: “Quarantined” | Repeated 5xx from AgentWatch | Check AgentWatch logs; restart provisioning after fixing |
| Users push, groups don’t | Groups mapping off, or group not assigned | B.12 toggle; assign the group itself in B.7 |
| Group members missing | Members not in scope | Scope is assigned users and groups — assign the group (its members follow) |
| Counts not moving | Initial cycle still running | Wait up to 40 min, or Provision on demand |
Reference
Section titled “Reference”- Microsoft OIDC: https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc
- Microsoft SAML SSO for non-gallery apps: https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/add-application-portal-setup-sso
- Microsoft SCIM: https://learn.microsoft.com/en-us/entra/identity/app-provisioning/use-scim-to-provision-users-and-groups
- Groups claim configuration: https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims