# Configuring Azure / Entra ID for SSO

## Overview

Crisisworks uses OAuth2 and OIDC to achieve a Single Sign-On (SSO) for users matching your authorised domains.

### Key concepts

At a high level, SSO works like this — when your users signs into Crisisworks, our OAuth2 service redirects the user to your Azure auth service, and then it converts the Azure authentication result into a Crisisworks user by mapping against a user's email address.

* Azure provides Authentication ("AuthN")
* Crisisworks manages Authorisation ("AuthZ") — via positions and events
* Crisisworks is multi-tenant and your SSO integration will cover only your internal users.&#x20;
* Your Crisisworks site will need to support external users, who will use their own SSO integration (if configured), or Crisisworks' internal username/password and MFA.&#x20;

For more non-technical overview, please read the [SSO Integration Overview](https://docs.cw.crisisworks.com/security-and-support/technical-reference/integrations/sso-integration) article.

### Open ID Connect (OIDC)

Crisisworks is built using an open standard known as "OAuth2", and uses OIDC to integrate to Azure.

1. **Your Azure service acts as an identity provider ("IdP")** — that means when someone logs in, they’ll be redirected to Azure to authenticate using your corporate credentials.
2. **Crisisworks acts as a “relying party” / “service provider”** — after successful login, Azure issues a token (ID token / access token) containing user attributes. Crisisworks' OAuth2 service then maps those attributes to our internal user directory, issues its own tokens, and grants access to our systems.

The following diagram shows the technical OAuth2/OIDC handshake.

{% @mermaid/diagram content="sequenceDiagram
participant U as User (Browser)
participant CW as Crisisworks Frontend / App
participant C as Crisisworks OAuth2 (SSO Broker / User Pool)
participant A as Azure IdP (Entra ID)

U->>CW: Access protected UI / “Sign in”
CW->>C: Redirect to Cognito /authorize (with configured IdP = Azure)
C->>A: Redirect to Azure /authorize endpoint (including client\_id, scopes, redirect\_uri, state, nonce)
A->>U: Azure login UI (or SSO session) → User enters credentials
A->>U: (login success) redirect back to C (Cognito) with **authorization\_code**
U->>C: (browser redirects) /token exchange, using code + client\_secret
C->>A: Backend: call Azure /token endpoint to exchange code → ID token / access token (if requested)
C->>A: Optionally, call Azure UserInfo endpoint to fetch extra claims
A->>C: Respond with ID token / access token / user info
C->>C: Validate signature, expiry, issuer, map claims to Cognito user attributes
C->>CW: Redirect user to app with JWT tokens (Cognito-issued)
U->>CW: Carry token in subsequent requests (e.g. Authorization header)" %}

## Configuring Azure (Entra ID)

The following guides Azure admins to set up the integration and provide the appropriate information to Datalink.

### Prerequisites

Your OIDC service should have the following configuration.

* Supports `client_secret_post` client authentication.
* Only uses HTTPS for OIDC endpoints such as `openid_configuration`, `userInfo`, and `jwks_uri`.
* Only uses TCP ports 80 and 443 for OIDC endpoints.
* Only signs ID tokens with HMAC-SHA, ECDSA, or RSA algorithms.
* Publishes a key ID `kid` claim at its `jwks_uri` and includes a `kid` claim in its tokens.
* Presents a non-expired public key with a valid root CA trust chain.

This configuration is common for Microsoft Azure Entra ID environments.

### Key information

Below is a mapping of the required fields in our SSO Integration Form and guidance on how to obtain them.

<table><thead><tr><th width="194.3125">Form Field</th><th>Description / Why Needed</th><th>Where to Configure or Obtain in Azure</th></tr></thead><tbody><tr><td>Provider type</td><td>Indicate you’re using OIDC</td><td>—</td></tr><tr><td>Provider name</td><td>A friendly name for your IdP (e.g. “Azure-Corp”)</td><td>You choose this — used for internal documentation / mapping</td></tr><tr><td>Issuer URL</td><td>OIDC issuer (used for discovery &#x26; token validation)</td><td>Typically <code>https://login.microsoftonline.com/{tenant}/v2.0</code> or your custom domain. </td></tr><tr><td>Client ID</td><td>The Application (client) ID from Azure</td><td>After you register the Azure app in Entra ID </td></tr><tr><td>Client secret</td><td>The client credential (secret) Azure issues</td><td>In App registrations → Certificates &#x26; secrets </td></tr><tr><td>Authorized scopes</td><td>The OIDC scopes your application requests (we require <code>openid</code>, <code>email</code>, <code>profile</code>)</td><td>In the app registration’s “Expose an API” or “API permissions” settings; or in your request to Azure. </td></tr><tr><td>Identifiers (domains)</td><td>The email domains for which your Azure instance is authoritative</td><td>You provide these; Azure doesn’t “enforce” routing for domains but this is for Crisisworks to know how to route</td></tr><tr><td>Attribute mappings (given_name, family_name, email, username and others)</td><td>Map claims from Azure to our internal user attributes</td><td>Use Azure app “Token configuration” or “Manifest” to add optional claims if needed</td></tr><tr><td>Optional: Secret expiry, rotation plan</td><td>If your secret expires, we need lead time to rotate</td><td>You decide expiry (e.g. 1 year, 2 years) and share process</td></tr></tbody></table>

### SSO Configuration Form

{% hint style="warning" %}
**Tip:** Use the Crisisworks SSO Integration Form to capture all the details in one place.

When complete, this form will contain sensitive information so care should be taken to transmit for form to Datalink and store the form in your records.
{% endhint %}

{% file src="<https://3923904090-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNy7IznbrPLUq6GJDDQDk%2Fuploads%2FUHa3a0uCLRo3jq1bztHk%2FSSO%20Integration%20Form%20Template%20V3%20DLSEC%20SENSITIVE.xlsx?alt=media&token=e7b4838c-ee7a-4fbe-94d1-4bb5a989fe30>" %}

## Suggested Steps

Use the following approach to configure Azure for Crisisworks.

### Initial set-up in Azure

{% hint style="info" %}
Check your Azure manual for exact steps
{% endhint %}

1. Register an application in Azure / Entra ID
   * Go to *Azure Portal → Entra ID → App registrations → New registration*&#x20;
   * Choose a name,&#x20;
   * Select single-tenant
   * Set "SPA" (Single Page Application) as the app type
   * Set the Redirect URI to \
     `https://auth.cw.crisisworks.com/oauth2/idpresponse`&#x20;
   * Set the Front-channel logout URL to\
     `https://app.cw.crisisworks.com/user/signout`&#x20;
2. Generate a client secret (or certificate)
   * Go to *Certificates & secrets* → New client secret (set expiry)
   * Copy the value (one-time view) — this is your Client Secret
3. Configure API permissions / scopes
   * Add delegated permissions: `openid`, `email`, `profile`
4. Add optional claims / token configuration
   * Select both ID token and Access token to allow the implicit flow
   * Required attributes: `email` , `given_name`, `family_name`&#x20;
   * Optional attributes: `verified_primary_email` (email verification flag) and `xms_edov` (domain verification flag)
5. Provide the configured values to Crisisworks
   * Issuer URL, Client ID, Client Secret, scopes, and the list of domains and attribute mappings via the [Crisisworks Configuration Form](#sso-configuration-form)

### Initial set-up in Crisisworks

Datalink configure your identity provider in Crisisworks

* We set up your OIDC provider in Cognito using those values
* We map your domains and configure routing

### Testing and validation

* You (or a pilot user) attempt login for users in your domain
* On success, a user’s browser should redirect to Azure, login, then return to Crisisworks
* We verify that correct user attributes (first name, last name, email, username) flowed through
* We test negative cases (domain not in your list, expired secret, token signature errors)
* Next we test signing into the mobile apps — iOS and Android.

### Go-live / rollout

* Once tests are successful, we enable SSO for full user base
* Monitor logs / errors in the first days

### Rotation and Troubleshooting

If the Client ID or secret require periodic rotation, this will be calendarised and Datalink will contact the nominated technical contact 30 days ahead of expiry.

From a tech support perspective, Datalink will no longer be able to troubleshoot failed login attempts for SSO users nor guide them to password resets, so a shared support approach will be organised and Datalink will refer the user to the support contact if the issue is related to signing into Azure.

## Testing / Verification Checklist

## SSO Testing Checklist

<table><thead><tr><th width="73.4140625">✅</th><th>Step</th></tr></thead><tbody><tr><td></td><td><strong>Testing success</strong></td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Use a test user with an email in your domain</td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Attempt login via Crisisworks SSO “Login with Azure” using the Crisisworks web app</td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Confirm the redirect to Azure, prompt, and return to Crisisworks</td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Confirm user attributes (first name, last name, email) appear correctly</td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Attempt the same SSO login via the Crisisworks app</td></tr><tr><td></td><td><strong>Error &#x26; edge-case testing</strong></td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Try login from an email outside your domain (should fall back to default login or error)</td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Try logging in with username and password from Crisisworks (should fail if SSO-only, and should work if supported as a fallback)</td></tr><tr><td></td><td><strong>Go-live cut-over</strong></td></tr><tr><td><ul class="contains-task-list"><li><input type="checkbox"></li></ul></td><td>Switch your user population from legacy login to SSO</td></tr><tr><td></td><td>Monitor first 24–48 hours for anomalous login failure spikes</td></tr></tbody></table>

## Further References & Resources

* [Microsoft: *OpenID Connect (OIDC) on the Microsoft identity platform*](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols-oidc?utm_source=chatgpt.com)&#x20;
* [Microsoft: *Configure OIDC SSO for custom applications in Entra ID*](https://app.gitbook.com/u/aNtBZyQV0TNvpzz3eOY5cC2n0yc2)&#x20;
* [Microsoft: *Quickstart for registering an app in Entra ID*](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app?utm_source=chatgpt.com)&#x20;
* [AWS / Cognito: *OIDC user pool IdP authentication flow*](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-oidc-flow.html?utm_source=chatgpt.com)&#x20;
* [Community: integration of Azure Entra ID with Cognito guides](https://nobuops.com/posts/entraid-cognito-oidc/?utm_source=chatgpt.com)&#x20;
