#Microsoft Entra ID setup
SignetMail uses one app registration in Microsoft Entra ID for three jobs:
- Portal sign-in — administrators sign in with their work account (single sign-on, MFA, Conditional Access).
- Add-in sign-in — the Outlook add-in obtains a token silently (Nested App Auth).
- 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
- Open Microsoft Entra admin center → Entra ID → App registrations → New registration.
- Name:
SignetMail. Supported account types: Accounts in this organizational directory only. - Leave the redirect URI empty for now and click Register.
- On the Overview page copy Application (client) ID and Directory (tenant) ID. These go into
.envasENTRA_CLIENT_IDandENTRA_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
- Expose an API → Application ID URI → Add and accept
api://<client-id>. - Add a scope: name
access_as_user, Who can consent: Admins and users, display name e.g. "Access SignetMail", state Enabled. - Open the Manifest and make sure
requestedAccessTokenVersionis2(underapi). Version 2 tokens containpreferred_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
- Certificates & secrets → Certificates → Upload certificate.
- Upload
certs/graph.cerproduced bysetup.shon the server (copy it to your computer, for example withscp). - 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:
- Token configuration → Add groups claim → Security groups.
- For the Access token choose Group ID.
- 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.
#7. Restrict who can sign in (strongly recommended)
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).
- Entra ID → Enterprise applications → SignetMail → Properties → Assignment required? = Yes.
- Users and groups → Add user/group — assign only the people who administer signatures.
- Conditional Access: create a policy that requires MFA (and preferably compliant devices) for the SignetMail application.
#8. Apply the settings
- Make sure
ENTRA_TENANT_ID,ENTRA_CLIENT_IDandPORTAL_OWNERare set in.env. - Restart the API:
sudo docker compose up -d(orsudo docker compose restart signetmail-api). - Check
https://<host>/health—lastSyncUtcshould be recent. - 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.