Integrate with Microsoft
Follow this step-by-step guide to allow SlashID to monitor and protect your Microsoft estate. A single Microsoft tenant connection covers your Entra ID directory (users, groups, service principals, managed identities, directory roles, app registrations and their credentials), your Azure resources (subscriptions, resources, RBAC role assignments), and Microsoft 365 (SharePoint sites and drives).
The directory is always synced. The Azure resources and Microsoft 365 capabilities are enabled by default and each requires its own permission grant, described below — if you skip a grant, the corresponding section of the sync is simply empty.
Before starting
Before starting, ensure you have:
- Global Administrator or Privileged Role Administrator privileges in your Microsoft Entra tenant, to create an app registration and grant admin consent to Microsoft Graph application permissions
- Owner (or User Access Administrator) on the Azure subscriptions you want to monitor, to create an Azure RBAC role assignment for the Azure resources capability
If your endpoint or tenant restricts traffic by source IP, allow connections from SlashID's egress IPs published at https://cdn.slashid.com/egress.json. The list is global and stable; the syncToken field changes whenever the IPs change, so you can use it to detect drift.
The file follows the JAFAR draft format (A JSON-Based Format for Publishing IP Ranges of Automated HTTP Clients), the same convention major cloud providers use to publish their IP ranges.
Step 1: Create an app registration
- Go to the Microsoft Entra admin center -> Identity -> Applications -> App registrations -> New registration
- Fill in:
- Name:
SlashID Identity Protection - Supported account types:
Accounts in this organizational directory only
- Name:
- Click Register
- On the app's Overview page, note the Application (client) ID and the Directory (tenant) ID — you will need both later.
Step 2: Create a client secret
- In the app registration, go to Certificates & secrets -> Client secrets -> New client secret
- Enter a description (e.g.
SlashID sync) and pick an expiry - Click Add
- Copy the secret Value immediately — it is only shown once.
When the secret expires, syncs will start failing with authentication errors. Create a new secret and update the connection in the SlashID Console before the expiry date.
Step 3: Grant Microsoft Graph application permissions
- In the app registration, go to API permissions -> Add a permission -> Microsoft Graph -> Application permissions
- Add the following permissions:
| Permission | What we sync |
|---|---|
User.Read.All | Users |
Group.Read.All | Groups and group memberships |
Application.Read.All | App registrations, service principals, managed identities, credentials |
RoleManagement.Read.Directory | Directory roles and role assignments |
Directory.Read.All | OAuth2 delegated permission grants (app consent on behalf of users) |
AuditLog.Read.All | Sign-in activity (last sign-in timestamps; needs an Entra ID P1/P2 license) |
Policy.Read.All | Conditional Access policies and their user/group/role scopes |
IdentityRiskEvent.Read.All | Identity Protection risk detections (needs an Entra ID P2 license) |
MailboxSettings.Read | Exchange inbox rules (only if you enable mailbox-rule sync — see below) |
CustomSecAttributeAssignment.Read.All | Custom security attributes assigned to users |
Sites.Read.All | SharePoint sites and drives (Microsoft 365 capability only) |
- Click Add permissions
- Click Grant admin consent for <your tenant> and confirm. Every permission must show a green "Granted" status.
Sites.Read.All is only required for the Microsoft 365 capability, and Directory.Read.All only for OAuth2 permission grants. If you skip either, the rest of the sync is unaffected — the corresponding data is simply absent.
To also receive near real-time audit events (sign-ins, role changes, SharePoint activity), additionally grant the Office 365 Management APIs permission:
- API permissions -> Add a permission -> Office 365 Management APIs -> Application permissions
- Add
ActivityFeed.Read - Click Grant admin consent again
Without this permission, scheduled syncs still work — you only lose event streaming between syncs.
Step 4 (optional): Assign the Azure Reader role
This step enables the Azure resources capability — Azure subscriptions, resources, and RBAC role assignments. Skip it if you only want directory and Microsoft 365 data.
- Go to the Azure portal -> Subscriptions -> select the subscription to monitor (or a management group to cover several subscriptions at once)
- Go to Access control (IAM) -> Add -> Add role assignment
- Under Role, select Reader
- Under Members, select User, group, or service principal and search for
SlashID Identity Protection(the app registration from Step 1) - Click Review + assign
Assigning Reader at the management group scope covers all subscriptions beneath it, including ones created later.
To also inventory the contents of your Key Vaults — the names of keys, secrets, and certificates, never their values — additionally assign the Key Vault Reader role (same steps as above, selecting "Key Vault Reader" instead of "Reader"). The plain Reader role only sees the vaults themselves; listing what is inside is a data-plane operation. Vaults without this access are skipped individually, so partial coverage works.
The Key Vault Reader role applies to vaults using Azure RBAC authorization. For vaults still using legacy access policies, grant the app a list access policy per vault — or skip them; they will simply be inventoried without their contents.
To also enumerate individual blobs (files) inside storage accounts as graph nodes, enable the Sync blob inventory toggle in the connection settings (Step 5). This is off by default. When enabled, it adds blobs to optional_crawls and walks every container in every storage account under the subscription. Storage containers are always enumerated as part of the Azure resources capability — the blob inventory opt-in goes one level deeper to list each object inside them.
Blob inventory is high-cardinality — a single storage account can hold millions or billions of objects. Enable it only when you need file-level inventory rather than container-level visibility.
Blob inventory requires an additional data-plane role: assign Storage Blob Data Reader on each storage account (or at the subscription scope to cover all accounts). The subscription-level Reader role from the step above grants management-plane access only and does not allow reading blob listings. Without Storage Blob Data Reader, the blob enumeration soft-fails per account — the rest of the sync is unaffected and the account's blobs are simply absent.
Step 5: Create Your Microsoft <> SlashID Integration
- Go to the SlashID Console -> Identity Protection -> Configuration -> Data sources.
- Click Add data source
- Select Microsoft from the list of providers in the select menu
- Enter your Microsoft connection details:
| SlashID Console field | Description | Example |
|---|---|---|
| Name of the connection | Arbitrary name you give to this connection | Microsoft Production |
| Authoritative status | Decide whether Microsoft Entra identities are the primary source of truth when reconciling identities across providers | Primary or Secondary |
| Directory (tenant) ID | The tenant ID from the app registration's Overview page (Step 1) | 00000000-0000-0000-0000-000000000000 |
| Application (client) ID | The client ID from the app registration's Overview page (Step 1) | 11111111-1111-1111-1111-111111111111 |
| Client secret | The client secret value you created in Step 2 | — |
- Optionally enable the deep-crawl options:
- Sync mailbox rules — inventories each user's Exchange inbox rules and flags rules that forward or redirect mail outside your tenant (a common persistence and exfiltration technique). Requires the
MailboxSettings.Readpermission from Step 3. The crawl makes one request per user, so it lengthens sync on large tenants. - Sync file-level permissions — inventories SharePoint/OneDrive files and their sharing permissions. This is the most expensive crawl (one pass over every file); enable it when you need file-level sharing visibility rather than site/drive granularity.
- Sync blob inventory — enumerates every blob (file) in every Azure storage account as a graph node. Requires Step 4 to be completed and the Storage Blob Data Reader role assigned on the storage accounts. See the note in Step 4 for cardinality and role requirements.
- Sync mailbox rules — inventories each user's Exchange inbox rules and flags rules that forward or redirect mail outside your tenant (a common persistence and exfiltration technique). Requires the
- Click Connect to complete the integration.
Event streaming
Once the connection is created, SlashID automatically subscribes to change streams that need no setup on your side:
- Directory changes — Microsoft Graph change notifications for users, groups, service principals, and applications
- Audit events — Office 365 Management Activity feeds
(
Audit.AzureActiveDirectory, andAudit.SharePointwhen the Microsoft 365 capability is enabled), providedActivityFeed.Readwas granted in Step 3
SlashID keeps these subscriptions alive and re-creates them automatically if they lapse.
Azure resource events (optional)
Streaming Azure resource changes (resource writes/deletes, RBAC role assignments) requires an Event Grid system topic subscription in each Azure subscription you monitor, because creating it needs write access we don't have with the Reader role. For each subscription:
az eventgrid event-subscription create \
--name slashid-identity-protection \
--source-resource-id "/subscriptions/<subscription-id>" \
--endpoint "https://api.slashid.dev/nhi/events/v2/microsoft_tenant/azure-resource-events" \
--endpoint-type webhook \
--included-event-types \
Microsoft.Resources.ResourceWriteSuccess \
Microsoft.Resources.ResourceDeleteSuccess \
Microsoft.Resources.ResourceActionSuccess \
--delivery-attribute-mapping Authorization static "Bearer <events token>" true
Replace <events token> with the connection's events token, shown on the
connection's details page in the SlashID Console. SlashID answers the Event
Grid validation handshake automatically. This step is optional: without it,
Azure resource changes are still picked up by every scheduled sync and the
90-day activity-log backfill — you only lose the near real-time signal.
Sign-in and Graph-activity log streaming (optional)
Real-time sign-in and Microsoft Graph activity detections — token replay, unfamiliar sign-ins, legacy-authentication usage, and Graph OAuth2 permission-grant manipulation — are driven by Entra ID's sign-in and Graph-activity logs. These logs are not part of the Graph change-notification, Management Activity, or Event Grid streams, so they require a separate route: an Entra ID diagnostic setting that streams the relevant log categories to an Event Hub you own, plus a small relay that forwards Event Hub records to SlashID. As with Event Grid, the connection's Reader role cannot create these resources, so the setup is yours to perform.
Create (or reuse) an Event Hub namespace and an event hub in your Azure subscription.
In the Azure portal, go to Microsoft Entra ID -> Monitoring -> Diagnostic settings -> Add diagnostic setting. Select the categories you want to stream —
SignInLogs,NonInteractiveUserSignInLogs,ServicePrincipalSignInLogs, andMicrosoftGraphActivityLogs— choose Stream to an event hub, and point it at the event hub from step 1.Deploy a relay (an Azure Function or Logic App triggered by the event hub) that POSTs each Event Hub message to SlashID:
POST https://api.slashid.dev/nhi/events/v2/microsoft_tenant/azure-monitor-logs
Authorization: Bearer <events token>
Content-Type: application/json
<the Event Hub message body verbatim>The endpoint accepts the raw Azure Monitor batch body (
{"records":[ … ]}), so the relay does not need to reshape records — it only forwards the message and attaches the bearer header. Use the same<events token>shown on the connection's details page.
This step is optional and customer-managed: the Event Hub namespace and its per-tenant cost are yours, and if the diagnostic setting or relay is absent the four sign-in / Graph-activity detections simply stay dark — the rest of the integration is unaffected.
Azure Storage resource-log streaming (optional)
Last-accessed edges — edges from an Entra user to individual blobs they read, wrote, or deleted — are built from Azure Storage resource logs. These logs are not exposed through Graph or Management Activity APIs; they must be streamed to an Event Hub via Azure Monitor diagnostic settings, then relayed to SlashID using the same endpoint as the sign-in log stream above. As with Event Grid and sign-in logs, the connection's Reader role cannot create diagnostic settings, so this setup is yours to perform.
For each storage account you want to track:
- In the Azure portal, go to the storage account -> Monitoring ->
Diagnostic settings -> select blob (the blob service, shown as
<storageAccountName>/blobServices/default) -> Add diagnostic setting. - Enable the log categories
StorageRead,StorageWrite, andStorageDelete. - Under Destination details, choose Stream to an event hub and select the same Event Hub namespace and event hub used for the sign-in log stream in the previous step. If you haven't set up that Event Hub yet, create one now and use it for both diagnostic settings.
- The relay you deployed for sign-in logs forwards records from the shared event hub to SlashID — no additional relay is needed, provided both diagnostic settings point at the same event hub.
Attribution caveat: only Entra-ID-authenticated (OAuth) data-plane operations carry a caller identity in Azure Storage resource logs. Access via SAS tokens or storage account keys produces no principal in the log record and therefore generates no last-accessed edge. Coverage is limited to Entra-authenticated data-plane access only.
This step is optional: without it, blob last-accessed edges are absent but the rest of the integration — including the pull blob inventory, if enabled — is unaffected.
Verification
After the first sync completes, SlashID will have synced:
- Entra directory: users, groups and memberships, service principals, managed identities, directory roles and assignments, app registrations together with their client secrets and certificates
- Entra extras (no additional permission): each user's manager, password-change recency, and devices discovered through group memberships. With
AuditLog.Read.All, per-application last-sign-in edges are aggregated from the 30-day sign-in log; withCustomSecAttributeAssignment.Read.All, custom security attributes land on user records. - PIM role eligibility (if your tenant has an Entra ID P2 license — no extra permission needed): principals that are eligible for a directory role are tracked alongside active assignments, and anyone eligible for a privileged role (e.g. Global Administrator) is classified as highly privileged — eligible admins are one self-activation away from the role. Tenants without P2 simply skip this.
- OAuth2 permission grants (if
Directory.Read.Allwas granted): which applications have delegated access to act on behalf of your users — and with which scopes — whether consented per user or tenant-wide by an admin - Sign-in activity (if
AuditLog.Read.Allwas granted and the tenant has an Entra ID P1/P2 license): each user's last interactive and non-interactive sign-in timestamps, used to surface stale and dormant accounts - Conditional Access policies (if
Policy.Read.Allwas granted): each policy with its state, MFA requirements, risk conditions, and which users, groups, and roles it includes or excludes — the input for CA posture checks such as missing-MFA coverage and over-broad exclusions - Identity Protection risk detections (if
IdentityRiskEvent.Read.Allwas granted and the tenant has an Entra ID P2 license): Microsoft's own risk verdicts — anomalous tokens, unfamiliar sign-in features, leaked credentials — linked to the affected users. Tenants without P2 simply skip this. - Hybrid identity links (no extra permission; requires an Active Directory connection in SlashID): users and groups synchronised from on-prem AD are deterministically linked to their AD counterparts by SID, so a hybrid human appears as one linked identity rather than two unrelated ones
- Azure (if Step 4 was completed): subscriptions, resources, and RBAC role definitions and assignments, including the effective access they grant
- Key Vault contents (if the Key Vault Reader role was assigned): the names of keys, secrets, and certificates in each readable vault — values are never read
- Blob inventory (if blob inventory sync was enabled and the Storage Blob Data Reader role was assigned): every blob in every storage account as a graph node. Storage accounts without the data-plane role are skipped — the rest of the sync is unaffected.
- Microsoft 365 (if
Sites.Read.Allwas granted): SharePoint sites and their document libraries / drives - Mailbox rules (if mailbox-rule sync was enabled and
MailboxSettings.Readgranted): inbox rules that forward or redirect mail, with external destinations flagged against your tenant's verified domains - File-level permissions (if file-level permission sync was enabled): every SharePoint/OneDrive file and folder with its sharing permissions — who can read, write, or share each item, plus flags for anonymous links and shares to external recipients. Large tenants are bounded by a per-sync inventory budget; truncation is recorded on the sync.
You can verify the connection in the SlashID Console under Identity Protection -> Configuration -> Data sources, where the connection card shows counts of synced users, groups, service principals, and applications.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
Authentication fails with 401 / invalid_client | The client secret is wrong or has expired | Create a new client secret (Step 2) and update the connection in the SlashID Console |
Sync fails with 403 Authorization_RequestDenied | A Microsoft Graph application permission is missing, or admin consent was not granted | Re-check Step 3: all listed permissions must be present and show "Granted" after admin consent |
| No Azure subscriptions or resources appear | The Reader role assignment for the app's service principal is missing | Complete Step 4 at the subscription or management-group scope |
| No SharePoint sites or drives appear | Sites.Read.All was not granted or not consented | Add Sites.Read.All as a Graph application permission and grant admin consent (Step 3) |