SignetMail docs Open portal →

#Microsoft Entra ID setup

SignetMail uses one app registration in Microsoft Entra ID for three jobs:

  1. Portal sign-in — administrators sign in with their work account (single sign-on, MFA, Conditional Access).
  2. Add-in sign-in — the Outlook add-in obtains a token silently (Nested App Auth).
  3. Directory access — the server reads users and groups through Microsoft Graph, authenticating with a certificate (no client secret to leak).

You need an account that can register applications and grant admin consent.

#1. Register the application

  1. Open Microsoft Entra admin center → Entra ID → App registrations → New registration.
  2. Name: SignetMail. Supported account types: Accounts in this organizational directory only.
  3. Leave the redirect URI empty for now and click Register.
  4. On the Overview page copy Application (client) ID and Directory (tenant) ID. These go into .env as ENTRA_CLIENT_ID and ENTRA_TENANT_ID.

#2. Sign-in redirect addresses

Authentication → Add a platform → Single-page application. Add:

Redirect URI Used by
https://<host>/portal/ The web portal (the trailing slash matters).
brk-multihub://<host> The Outlook add-in (Nested App Auth). Required for the add-in to sign in silently.

Click Configure. Do not tick any Implicit grant boxes. Remove any other redirect URIs (for example leftovers from testing) that you do not need.

#3. Expose an API

  1. Expose an API → Application ID URI → Add and accept api://<client-id>.
  2. Add a scope: name access_as_user, Who can consent: Admins and users, display name e.g. "Access SignetMail", state Enabled.
  3. Open the Manifest and make sure requestedAccessTokenVersion is 2 (under api). Version 2 tokens contain preferred_username, which SignetMail uses to identify the person.

#4. Permissions

API permissions → Add a permission.

First, let the portal call the API:

  • My APIs → SignetMail → Delegated → access_as_user.

Then let the server read the directory:

  • Microsoft Graph → Application permissions (not Delegated):
Permission Needed for
User.Read.All Reading users and their attributes (name, title, department, phone, extension attributes). Required.
Group.Read.All Listing groups so you can pick them in rules and campaigns.
GroupMember.Read.All Reading group membership so group-based rules match the right people.

Finally click Grant admin consent for <your tenant> and confirm that every row shows a green check mark.

Note. Without the two group permissions SignetMail still works for people and attribute-based rules. The portal shows a warning instead of the group list, and group-based rules and group-based roles have no effect.

#5. Certificate

  1. Certificates & secrets → Certificates → Upload certificate.
  2. Upload certs/graph.cer produced by setup.sh on the server (copy it to your computer, for example with scp).
  3. Do not create a client secret. Certificate authentication is stronger and the private key never leaves the server.

The certificate is valid for 730 days. Put the expiry date in your calendar; renewal takes a few minutes.

#6. Roles from Entra groups (optional)

To grant portal roles to a security group instead of each person (Access and roles), the sign-in token must contain the user's groups:

  1. Token configuration → Add groups claim → Security groups.
  2. For the Access token choose Group ID.
  3. Prefer Groups assigned to the application so tokens stay small. When a user belongs to too many groups, Entra omits the list (the "groups overage" case) and the portal shows a warning; in that case only roles granted directly to the person apply.

By default every user in your tenant could try to open the portal (they would then see "no access", but you should not rely on that).

  1. Entra ID → Enterprise applications → SignetMail → Properties → Assignment required? = Yes.
  2. Users and groups → Add user/group — assign only the people who administer signatures.
  3. Conditional Access: create a policy that requires MFA (and preferably compliant devices) for the SignetMail application.

#8. Apply the settings

  1. Make sure ENTRA_TENANT_ID, ENTRA_CLIENT_ID and PORTAL_OWNER are set in .env.
  2. Restart the API: sudo docker compose up -d (or sudo docker compose restart signetmail-api).
  3. Check https://<host>/health — lastSyncUtc should be recent.
  4. Open https://<host>/portal/ and sign in as the owner.

#Common errors

Message Cause and fix
AADSTS50011 — reply URL does not match The redirect URI https://<host>/portal/ is missing or has no trailing slash. Add it under Authentication → Single-page application.
Groups list shows Insufficient privileges Group.Read.All / GroupMember.Read.All missing as Application permissions or admin consent not granted. Fix it, then restart signetmail-api.
"No access" after signing in Your UPN is not PORTAL_OWNER and no role has been granted to you. Ask an Owner to add you under Access.
Sign-in loop or AADSTS700016 ENTRA_CLIENT_ID or ENTRA_TENANT_ID in .env is wrong.
Add-in cannot sign in brk-multihub://<host> redirect URI missing.

More in Troubleshooting.

SignetMail documentation · version main