Microsoft Entra ID (Azure AD)

How to set up Microsoft Entra ID, formerly Azure Active Directory, as an external identity provider for Stroom.

This page covers using Microsoft Entra ID as Stroom’s Identity Provider (IDP) Identity Provider (IDP) An Identity Provider is a system or service that can authenticate a user and assert their identity. Identity providers can support single sign on (SSO), which allows the user to sign in once to the Identity Provider so they are then authenticated to all systems using that IDP.Click to see more details.... Entra ID is the current name for what was Azure Active Directory, and much of the tooling and documentation still says Azure AD.

Entra ID has two generations of endpoint, v1.0 and v2.0, which issue tokens with different issuers and different formats. Two of the three things most likely to go wrong here come from mixing them up, so it is worth being deliberate: use the v2.0 endpoints throughout.

Creating the App Registration

In the Microsoft Entra admin centre , or the Azure portal under Microsoft Entra ID:

  1. Go to App registrations => New registration.
  2. Give it a name, e.g. Stroom.
  3. For Supported account types choose Accounts in this organizational directory only, i.e. single tenant, unless you have a specific reason not to. This restricts sign in to your own tenant.
  4. Under Redirect URI select a platform of Web and enter https://STROOM_FQDN/api/auth/flow/v1/signin-oidc.
  5. Click Register, then note the Application (client) ID and the Directory (tenant) ID from the overview page.

Where STROOM_FQDN is the public address of Stroom, i.e. what you have set as appConfig.publicUri.

Then, still in the app registration:

  1. Under Authentication, add a Front-channel logout URL of https://STROOM_FQDN/, and add the same value under Redirect URIs if your tenant requires post logout redirect URIs to be registered.
  2. Under Certificates & secrets => Client secrets, create a new secret and copy its Value immediately, as it is only shown once.

Entra ID supports PKCE, and Stroom always sends an S256 challenge, so there is nothing to configure for it.

Exposing an API for Access Tokens

This step is what makes API authentication work, and is the Entra ID equivalent of KeyCloak’s audience mapper.

If Stroom only ever asks for the openid, email and profile scopes, Entra ID issues an access token for Microsoft Graph rather than for Stroom. Those tokens are intended only for Graph, are not in a format a third party can validate, and will fail validation at Stroom. Interactive sign in still works throughout, because it uses the id_token.

To get an access token that Stroom can validate, the app registration has to expose an API of its own:

  1. Go to Expose an API => Add next to Application ID URI. Accept the default of api://<client-id>, or set your own.
  2. Click Add a scope, name it something like user_impersonation, and choose who can consent.
  3. Under Manifest, set accessTokenAcceptedVersion to 2.

Callers then request that scope, e.g. api://<client-id>/user_impersonation, and the resulting access token carries an aud claim that Stroom can be configured to accept.

Configuring Stroom

  receive:
    # Set to true to require authentication for /datafeed requests
    authenticationRequired: true
    # Set to true to allow authentication using an Open ID token
    tokenAuthenticationEnabled: true
  security:
    authentication:
      authenticationRequired: true
      openId:
        identityProviderType: EXTERNAL_IDP
        # Note the '/v2.0' path part. Without it you get the v1.0 endpoints and a different issuer.
        openIdConfigurationEndpoint: "https://login.microsoftonline.com/TENANT_ID/v2.0/.well-known/openid-configuration"
        # The Application (client) ID from the app registration overview
        clientId: "11111111-2222-3333-4444-555555555555"
        clientSecret: "THE_CLIENT_SECRET_VALUE"
        logoutEndpoint: "https://login.microsoftonline.com/TENANT_ID/oauth2/v2.0/logout"
        # Accept both the id_token audience (the client id) and the access token audience
        # (the Application ID URI). Adjust to match what your tokens actually carry.
        allowedAudiences:
          - "11111111-2222-3333-4444-555555555555"
          - "api://11111111-2222-3333-4444-555555555555"

Replace TENANT_ID with the Directory (tenant) ID.

Issuers

The v2.0 discovery endpoint advertises an issuer of https://login.microsoftonline.com/TENANT_ID/v2.0, which is a parent path of the discovery endpoint itself, so Stroom’s issuer check is satisfied with no extra configuration.

The v1.0 endpoints are not so tidy. Their issuer is https://sts.windows.net/TENANT_ID/, which shares no base URI with the discovery endpoint, and Stroom will refuse to start with:

Issuer ‘X’ obtained from configuration endpoint Y does not share the same base URI.

If you must use v1.0, or you have v1.0 access tokens in circulation from an app registration you cannot change, list the issuer explicitly:

        validIssuers:
          - "https://sts.windows.net/TENANT_ID/"

Using the v2.0 endpoints and accessTokenAcceptedVersion: 2 is much the better answer.

Audience Validation

An Entra ID id_token carries aud set to the Application (client) ID, so interactive sign in validates against clientId with no further configuration.

An access token for your exposed API carries aud set to either the Application ID URI or the client id, depending on accessTokenAcceptedVersion and how the scope was requested. Listing both in allowedAudiences, as above, covers either.

Leave validateAudience at its default of true.

Claims

The Stroom defaults suit Entra ID v2.0. It issues preferred_username, normally the user principal name, which Stroom uses as the display name, and name, which satisfies the default fullNameClaimTemplate of ${name}.

For uniqueIdentityClaim you have a choice:

Claim Notes
sub The Stroom default. In Entra ID this is pairwise, i.e. a different value per application, and stable for the life of that app registration. Delete and recreate the app registration and every user’s sub changes, orphaning their Stroom user.
oid The user’s object id in the directory. Stable across applications and across app registrations, so it survives a re-registration. Unique within a tenant.

oid is the more robust choice for a single tenant deployment, and is what Microsoft’s own guidance points to as the durable identifier. sub is fine if you are confident the app registration will not be recreated.

        uniqueIdentityClaim: "oid"

Group and Role Claims

Entra ID can be configured to emit groups and roles claims. Stroom does not consume them. All authorisation is done with Stroom’s own users, groups and permissions, so directory group membership has no effect on what a user can do in Stroom.

Access Token Type

Leave requiredAccessTokenType unset until you have decoded the header of a real access token from your tenant and confirmed what it contains. Setting it to a value your tokens do not use will refuse every API call.

Setting up the Admin User in Stroom

Find the identifier of the account that is to be the administrator, matching whatever you set uniqueIdentityClaim to.

If you are using oid, it is shown as the Object ID on the user’s page under Users in the Entra admin centre. If you are using sub, it is pairwise and not shown anywhere in the portal, so you will need to decode an id_token issued for that user, or have them sign in once and read it from the Stroom logs.

Then run the following, ideally before Stroom has been started for the first time:

subject_id="XXX"; \
java -jar /absolute/path/to/stroom-app-all.jar \
  manage_users \
  --createUser "${subject_id}" \
  --createGroup Administrators \
  --addToGroup "${subject_id}" Administrators \
  --grantPermission Administrators "Administrator" \
  ../local.yml

The command is repeatable and will skip anything that already exists, so running it against a user who has already signed in is fine. Restart Stroom afterwards if it was running, as permissions are cached.

Stroom-Proxy with Entra ID

A Stroom-Proxy obtains a token for its own service user using the client credentials grant.

Create a second app registration for the proxy, then grant it access to the API exposed by the Stroom app registration:

  1. In the proxy’s app registration, go to API permissions => Add a permission => My APIs and select the Stroom app registration.
  2. Choose Application permissions, which is the client credentials case, rather than delegated permissions.
  3. Have a directory administrator grant admin consent, without which the grant will fail.

Entra ID’s client credentials flow uses the .default scope of the target API:

  security:
    authentication:
      openId:
        identityProviderType: EXTERNAL_IDP
        openIdConfigurationEndpoint: "https://login.microsoftonline.com/TENANT_ID/v2.0/.well-known/openid-configuration"
        clientId: "THE_PROXY_CLIENT_ID"
        clientSecret: "THE_PROXY_CLIENT_SECRET"
        clientCredentialsScopes:
          - "api://11111111-2222-3333-4444-555555555555/.default"

The destination the proxy forwards to must accept the audience these tokens carry, which will be the Application ID URI or client id of the Stroom app registration, so make sure it appears in that destination’s allowedAudiences.

Last modified August 14, 2026: fix build (307b3f0)