Microsoft 365 OAuth Setup
- 1
1. Register the app. Go to Azure Portal → App registrations → New registration.
- 2
2. Name and account types. Name: e.g. 'ClearFox Portal'. Supported account types: 'Accounts in this organizational directory only' (single tenant).
- 3
3. Redirect URI. Under Redirect URI, add (replace with your portal URL):
https://ai.yourcompany.com/api/auth/callback/azure-ad - 4
4. Second redirect URI. After creation, go to Authentication → Add a platform → Web. Add the second redirect URI:
https://ai.yourcompany.com/api/oauth/callback - 5
5. Client secret. Go to Certificates & secrets → New client secret. Copy the Value (not Secret ID).
- 6
6. Tenant and client IDs. Copy the Application (client) ID and Directory (tenant) ID from the app's Overview page.
- 7
7. Add API permissions (delegated). Open the app registration → API permissions → Add a permission → Microsoft Graph → Delegated permissions. Always choose Delegated, never Application: the token acts as the signed-in user, so a connected account can only reach the mailboxes, files, sites and chats that this account already has access to in Microsoft 365. Find each permission with the search box, tick it, then click Add permissions.
- 8
8. The permissions ClearFox requests. Every Microsoft integration also needs User.Read and offline_access (the latter is listed under OpenId permissions in the picker) — without
offline_accessEntra returns no refresh token and the connection dies within the hour. On top of that, add the groups for the integrations you will actually use:
Outlook Mail (ms-mail) — Mail.ReadWrite, Mail.Send
Outlook Calendar (ms-calendar) — Calendars.ReadWrite, People.Read
Excel (ms-excel) — Files.ReadWrite.All
Files / OneDrive / SharePoint (ms-files) — Files.Read.All, Sites.Read.All
Teams (ms-teams) — Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Send, Chat.ReadWrite, User.ReadBasic.All (resolves colleagues for @mentions)
Full list to work through in the picker (lines starting with # are group labels, not permissions):# every integration User.Read offline_access # Outlook Mail (ms-mail) Mail.ReadWrite Mail.Send # Outlook Calendar (ms-calendar) Calendars.ReadWrite People.Read # Excel (ms-excel) Files.ReadWrite.All # Files / OneDrive / SharePoint (ms-files) Files.Read.All Sites.Read.All # Teams (ms-teams) Team.ReadBasic.All Channel.ReadBasic.All ChannelMessage.Send Chat.ReadWrite User.ReadBasic.All - 9
9. Grant admin consent. Still on API permissions, click Grant admin consent for <your tenant> and confirm — this needs a Global Administrator or Privileged Role Administrator. Do not skip it: under the default tenant user-consent policy a regular employee may only self-consent to the low-impact permissions (User.Read, offline_access, openid/profile/email). Everything else from step 8 — Mail.ReadWrite, Mail.Send, Calendars.ReadWrite, Files.Read.All, Files.ReadWrite.All, Sites.Read.All and the Teams permissions — requires this one-time tenant-wide consent, otherwise every user hits the “Need admin approval” screen the moment they click Connect. An admin who prefers a URL can grant it here instead (replace both placeholders):
https://login.microsoftonline.com/<tenant-id>/adminconsent?client_id=<application-client-id> - 10
10. Paste the credentials into ClearFox. In ClearFox Admin → OAuth, open the Microsoft subtab, switch the mode to My own OAuth app, and paste the Tenant ID, Client ID, and Client Secret. The same Azure app powers both integrations and portal sign-in (SSO) — register both redirect URIs in the same app registration.
- 11
Still getting “Need admin approval” (AADSTS90094)? Admin consent has not been granted for the permission that integration requests. Go back to API permissions, confirm the Status column reads “Granted for <tenant>” on every row, add anything missing from step 8, and click Grant admin consent again — adding an integration later means new permissions, so consent has to be re-granted. See also Needs admin approval / admin consent required.