Insider Risk Management Part 4: Creating your first policy

Insider Risk Management Part 4: Creating your first policy

Series: This is Part 4 of 7 in my series on Microsoft Purview Insider Risk Management. New to the series? Start with the series guide, which summarises every part.

In this post I create a Data theft by departing users policy from start to finish in the Microsoft Purview portal. I also explain who needs which permissions and what the HR connector is, and share two PowerShell scripts and a set of KQL queries to set up, test and hunt. Every screenshot comes from my test environment, including the warnings and gaps I hit along the way.

Why start with departing users?

Remember the email from Part 1: every person who had resigned had moved data out of the organisation. That scan tells you the problem exists, but it does not raise an alert about any individual. A Data theft by departing users policy does. That is why it is the first policy I recommend every organisation creates.

Before you start

  1. Licensing. Covered in Part 3.
  2. Audit logging. Microsoft 365 keeps a log of user activity, and Insider Risk Management relies on it. It is on by default, but some organisations have turned it off. My test environment flagged it as something to check.
  3. Permissions. Covered below.
  4. Analytics (recommended). Turn on analytics in the Insider Risk Management settings. It scans for risky activity across the organisation and can take up to 48 hours to report back.
  5. Indicators. The activities Insider Risk Management watches for are switched on in its settings. If they are off, the policy set-up stops you, as it did for me.
  6. Connections to other systems. The HR connector for the leavers policy, and laptops connected to Microsoft Defender for Endpoint so their activity can be seen.
The Insider Risk Management overview lists the recommended setup actions

Required roles

Insider Risk Management has its own permission groups, called role groups. They are separate from the usual administrator roles on purpose: the people who set up policies should not automatically be able to see who is being investigated.

Role group What it allows
Insider Risk Management Full access to every Insider Risk Management feature. Use for small teams or a single lead investigator.
Insider Risk Management Admins Configure policies and settings, Adaptive Protection, analytics and forensic evidence requests. Cannot investigate alerts.
Insider Risk Management Analysts Triage alerts and cases, view analytics and reports. Users are pseudonymised.
Insider Risk Management Investigators Investigate alerts and cases, view forensic evidence and use Content explorer.
Insider Risk Management Auditors View and export the Insider Risk Management audit log only.
Insider Risk Management Approvers Approve forensic evidence capture requests only.
Insider Risk Management Session Approvers Visible in the portal alongside the others. Relates to forensic evidence session approval.

Senior administrators, such as Global Administrators and Compliance Administrators, can set up Insider Risk Management, but they cannot see alerts or investigations. My test environment shows this perfectly. I created the policy without a problem, but the Policies page warned that I could not see the alerts it would produce:

Admin access lets you build policies, but not see the alerts they generate
All seven Insider Risk role groups had no members
My access came from Organization Management and Purview Administrators

Recommendation: Put the people who set up policies in the Admins role group, and your compliance officers – not IT – in the Analysts or Investigators role group. Keep the two separate and keep both small. For the roles that can see alerts and reveal names, add a PIM-enabled security group rather than individual people, as described in Part 1, so access is only switched on when needed. Changes can take up to 30 minutes to take effect.

The HR connector explained

Insider Risk Management needs to know when someone is leaving, and Microsoft 365 cannot work that out on its own. The HR connector is how you tell it. It takes a simple spreadsheet file (a CSV) exported from your HR system and feeds it into Purview. As well as resignations, it can share job changes such as demotions, performance reviews and performance improvement plans.

How the HR connector tells Insider Risk Management someone is leaving

For leavers, the file only needs three columns – who, when they resigned, and their last working day:

UserPrincipalName,ResignationDate,LastWorkingDate
engineer@contoso.com,2026-10-24T09:00:00Z,2026-11-21T17:00:00Z
  1. Create an app registration in Microsoft Entra ID. This gives the upload process its own secure identity. Note its application ID, tenant ID and client secret.
  2. Create the HR connector in Purview under Settings > Data connectors, tell it which column is which, and copy the job ID it gives you.
  3. Upload the file using Microsoft’s sample PowerShell script. The computer running it must be allowed through your firewall to webhook.ingestion.office.com.
  4. Schedule it to run daily, or use Microsoft’s Power Automate template to upload automatically whenever HR saves a new file to SharePoint or OneDrive.

Resignation data is used by the two leaver templates. Job changes and performance data are used by the risky user templates.

No HR connector yet? You can still create the policy. It will use “User account deleted from Microsoft Entra ID” as the trigger instead. That usually happens after the person has already left – too late to stop the data walking out – so treat it as a temporary fix.

Walkthrough: creating the policy

Go to Insider Risk Management in the Purview portal, open Policies and select Create policy.

Step 1 – Start a custom policy

A quick policy fills in sensible defaults for you. A custom policy walks through every setting, which is what I use here so you can see each option.

Create policy > Custom policy

Step 2 – Choose the template

Select Data theft by departing users. The panel on the right shows what the template needs: the HR connector is recommended, and my laptops are already connected.

Data theft by departing users and its prerequisites

Scroll down to see what starts the policy and what activity it looks for. You can also see the other templates, including Risky AI usage, and a separate tab for AI agent policies.

Triggering events and detected activities

Step 3 – Name and describe the policy

Policy name and description

Step 4 – Choose users and groups

I kept the default of all users in my test environment. In a real organisation, consider starting with a pilot group, and remember everyone covered needs a licence. On the next screen you can leave out test or system accounts.

Users, groups and adaptive scopes
Optional exclusions

Step 5 – Content to prioritise

Here you can tell Insider Risk Management which data matters most – specific SharePoint sites, sensitivity labels, or types of sensitive information such as credit card numbers. Activity involving that data scores higher. For a first policy I skipped this. You can add it later, and it is where your labelling work really starts to pay off.

Prioritise SharePoint sites, labels, sensitive info types, extensions and classifiers

Step 6 – Triggering event

Because my test environment has no HR connector, the set-up selects “User account deleted from Microsoft Entra ID” and explains why.

Entra ID account deletion is the fallback trigger

Step 7 – Indicators

This is where my test environment stopped me. The activities the policy needs to watch were switched off for the whole organisation:

Indicators turned off at the organisation level

Selecting Turn on indicators changes a setting for the whole organisation – every insider risk policy can then use them.

Turning on indicators changes a setting for the whole organisation

After selecting Turn on all, 77 of the 105 available indicators were switched on for this policy.

Indicators selected for the policy

Step 8 – Detection options

Sequence detection is on by default. It looks for a chain of steps within seven days – downloading data, disguising it, moving it out and deleting the evidence.

Sequence detection options

Step 9 – Indicator thresholds

Thresholds decide how much activity counts as unusual. Start with Microsoft’s, and fine-tune them once analytics has learned what is normal for your organisation.

Use Microsoft thresholds to start with

Step 10 – Review and submit

The policy starts straight away, but it can take up to 24 hours before the first alerts appear.

Review settings
The policy is created
The new policy is live and healthy

Automating with PowerShell

Microsoft does not provide a supported PowerShell command for creating insider risk policies, so the policy itself has to be created in the portal. The companion script, Invoke-InsiderRiskSetup.ps1, automates everything around it instead:

  1. Checks audit logging is on, and can turn it on for you
  2. Adds people to the Insider Risk Management role groups
  3. Shows which insider risk PowerShell commands are available to you
  4. Confirms your policy exists and saves a copy of its settings for your records

The scripts, the KQL hunting queries and their README files are on GitHub: https://github.com/cloud-secure-ai/Purview-insider-risk-management

.\Invoke-InsiderRiskSetup.ps1 `
    -AdminUpn admin@contoso.com `
    -AnalystUpn analyst@contoso.com `
    -InvestigatorUpn investigator@contoso.com `
    -EnableAuditing -WhatIf

Proving it works

A policy is only useful if it catches something. The second companion script, Invoke-InsiderRiskSimulation.ps1, plays the part of a leaver in a test environment. It creates files containing dummy sensitive data, downloads them from SharePoint, zips them up and renames the archive to hide what it is, copies it to a USB stick or a personal cloud folder, can email a few files to an outside address, and then deletes the evidence.

Run it as a test user, on a laptop connected to Microsoft Defender for Endpoint. First bring that user into scope with Start scoring activity for users on the Policies page, or upload a resignation date for them through the HR connector. Every step is written to a log file with a timestamp, so you can match it against the alert. Alerts can take up to 24 hours to appear.

Test environments only: The simulation deliberately behaves like someone stealing data. It will not run unless you confirm it is a test environment, and it checks it is signed in to the test organisation you name. Never run it in production.

Hunting with KQL

Insider Risk Management alerts also appear in the Microsoft Defender portal, where your security team already works. There you can search the underlying activity yourself using advanced hunting. Advanced hunting uses KQL (Kusto Query Language) – you paste a query in, select Run query, and get a table of results.

Two settings matter before Insider Risk data shows up in Defender. First, turn on Sharing data with other Microsoft security solutions under Insider Risk Management settings > Data sharing. Second, the person hunting must be in the Insider Risk Management Analysts or Investigators role group – the same admin-versus-analyst split covered earlier.

This query lists every file copied to a USB stick or other removable drive, with the make, model and serial number of the device it went to:

DataSecurityEvents
| where Timestamp > ago(30d)
| where DeviceDestinationLocationType == 3
| project Timestamp, AccountUpn, DeviceName, ObjectName, ObjectSize,
          RemovableMediaManufacturer, RemovableMediaModel, RemovableMediaSerialNumber
| order by Timestamp desc

You do not need Insider Risk Management for the next one. It uses standard Defender data, so you can run it in any organisation with Defender today. Add your recent leavers and their last working day, and it shows every SharePoint or OneDrive download, every zip file created on their laptop and every email with attachments they sent outside, in the 30 days before they left:

let Leavers = datatable(AccountUpn: string, LastWorkingDay: datetime) [
    "leaver1@contoso.com", datetime(2026-11-21),
    "leaver2@contoso.com", datetime(2026-12-05)
];
let LookbackDays = 30d;
let LeaverUpns = Leavers | project AccountUpn = tolower(AccountUpn);
let CloudDownloads = CloudAppEvents
    | where Timestamp > ago(90d)
    | where ActionType == "FileDownloaded"
    | extend AccountUpn = tolower(tostring(RawEventData.UserId))
    | where AccountUpn in (LeaverUpns)
    | project Timestamp, AccountUpn, Activity = "Downloaded from SharePoint or OneDrive",
              Detail = ObjectName, Application;
let ArchivesCreated = DeviceFileEvents
    | where Timestamp > ago(90d)
    | where ActionType in ("FileCreated", "FileRenamed")
    | where FileName matches regex @"(?i)\.(zip|7z|rar|tar|gz|dat)$"
    | extend AccountUpn = tolower(InitiatingProcessAccountUpn)
    | where AccountUpn in (LeaverUpns)
    | project Timestamp, AccountUpn, Activity = strcat("Archive ", tolower(ActionType), " on device"),
              Detail = strcat(DeviceName, " - ", FolderPath), Application = InitiatingProcessFileName;
let ExternalEmail = EmailEvents
    | where Timestamp > ago(90d)
    | where EmailDirection == "Outbound" and AttachmentCount > 0
    | extend AccountUpn = tolower(SenderFromAddress)
    | where AccountUpn in (LeaverUpns)
    | project Timestamp, AccountUpn, Activity = "Email with attachments sent outside",
              Detail = strcat(RecipientEmailAddress, " - ", Subject), Application = "Exchange Online";
union CloudDownloads, ArchivesCreated, ExternalEmail
| join kind=inner (Leavers | extend AccountUpn = tolower(AccountUpn)) on AccountUpn
| where Timestamp between ((LastWorkingDay - LookbackDays) .. (LastWorkingDay + 1d))
| project Timestamp, AccountUpn, LastWorkingDay, Activity, Detail, Application
| order by AccountUpn asc, Timestamp asc

Try this: Run the leaver timeline against the last five people who left your organisation. If it returns anything, you have just found what Insider Risk Management would have alerted you to – and that is usually the most persuasive business case there is.

The full set of seven queries – including Insider Risk alerts by person, sensitivity label changes and a query that finds a run of the simulation script – is on GitHub with a README explaining each one.

In Part 5 I connect this policy to Adaptive Protection and DLP, so that a high risk score automatically tightens the controls for that person.


The rest of the series

References

Seรกn O’Farrell | cloud-secure.ai

How to Set Up Multi-Tenant Management in Microsoft Defender XDR

Multi-tenant management in Microsoft Defender XDR (MTO) is designed to provide security operation teams with a single, unified view of all the tenants they manage. This feature allows teams to quickly investigate incidents and perform advanced hunting across data from multiple tenants, thereby improving their security operations.

Multi-tenant management in Microsoft Defender XDR became generally available (GA) on February 20th, 2024.

A copilot search can provide more details ๐Ÿ™‚

Blog Purpose

The goal of this blog post is to show you how to set up multi-tenant management in Microsoft Defender XDR with the least privilege needed. Multi-tenant management in Microsoft Defender XDR allows you to manage and monitor multiple tenants from a single console. This feature was released for general availability (GA) on February 20th, 2024.

Topology Scenario

Source tenant : Contoso.com
Target tenant : Fabrikam.com

Typically, I choose a hub and spoke topology. Source and target tenantsโ€™

Roles

Global Admin Role, is required for the initial set up in the โ€˜Contoso.comโ€™ source tenant, when configuring the โ€˜cross tenantโ€™ configurations

Browser Sessions

Sometimes using multiple Microsoft Edge profiles to sign into the source tenant and the target tenants can cause problems, due to cookies and too many Edge active browser sessions.

Typically, I use the Microsoft Edge browser in private window option to sign into the source โ€˜Contso.comโ€™ tenant

And then Google Chrome โ€˜Incognito Modeโ€™ session to sign into the target โ€˜Fabrikam.comโ€™ tenant.

#####Step 1

Log into the target tenant โ€˜Fabrikam.comโ€™, browse to https://entra.microsoft.com/ / external identities/ cross-tenant access settings

Select โ€˜Add organizationโ€™ and add the tenant id for โ€˜Contoso.comโ€™

When the Contoso organization has been added to Fabrikam.com, select the inbound access/ cross-tenant sync and select โ€˜Allow users sync into this tenantโ€™

Select the inbound access/ trust settingsย  โ€˜Automatically redeem invitations with the tenantโ€™
(Typically, this setting will automatically be selected, but just in case, it needs to be checked)

#####Step 2

Log into the target tenant โ€˜Contoso.comโ€™, browse to https://entra.microsoft.com/ ย external identities/ cross-tenant access settings

Select โ€˜Add organizationโ€™ and add the tenant id for โ€˜Fabrikam.comโ€™

When the organisation โ€˜Fabrikam.com has been added, select Outbound Access/ trust settings/ automatically redeem invitations with the tenant Fabrikam

#####Step 3

Now login to โ€˜Contoso.comโ€™ and browse to , browse to https://entra.microsoft.com/ / external identities/ cross-tenant access settings

Select โ€˜Add organizationโ€™ and add the tenant id for โ€˜Fabrikam.comโ€™

In the source tenant โ€˜Contoso.comโ€™ / cross-tenant access settings, select โ€˜Fabrikam.comโ€™ outbound settings / trust settings

#####Step 4

This section is where global admin privileges are required in the source tenant โ€˜Contoso.comโ€™

Browse to Contos.com | cross-tenant synchronization > Cross-tenant synchronisation

Select new configuration

Provide a name for your configuration

It can take up to 60 seconds for the configuration to be created, if the browser session appears like it is hung, JUST WAIT!

Select โ€˜Get Startedโ€™

Change the provisioning mode, authentication mode and tenant ID as per the image below.

When pressing save, the browser session does not revert to the global cross-tenant synchronization / cross-tenant synchronization / configurations GUI.

#####Step 5

At this stage we will configure the provisioning configuration.

Select the โ€˜Contoso โ€“ Fabrikam organizationโ€™

Add the admin user accounts from the source tenant โ€˜Contoso.comโ€™ that will be provisioned into โ€˜Fabrikam.comโ€™

Select the provisioning status and change it from off to on.

Within the provisioning overview section, select โ€˜Restart provisioningโ€™

Note: Do not keep clicking on โ€˜start provisioningโ€™ , โ€˜stop provisioningโ€™ and โ€˜restart provisioningโ€™ , be patient and wait!

#####Step 6

To access the security data of the ‘Fabrikam.com’ tenant, the admin users from ‘Contoso.com’ need to be assigned the ‘Security reader’ role in ‘Fabrikam.com’. This role allows them to view security reports and alerts, but not to make any changes.

However, if ‘Fabrikam.com’ has Privileged Identity Management (PIM) enabled and is an Enterprise Identity Protection 2 (EIP2) tenant, there is an extra step involved.

The ‘Security reader’ role assignment must be activated through PIM, either for a specific duration or as permanently eligible. Note that the permanent option is not really permanent, it still expires after 6 months and needs to be renewed manually.

Therefore, it is recommended to set a reminder to check the PIM role assignments in ‘Fabrikam.com’ and renew the ‘Security reader’ role for the ‘Contoso.com’ admin accounts when necessary.

โ€˜Security Readerโ€™ role can manually be added per Contoso admin in Fabrikam or a Microsoft Entra ID security group can be created and assigned the โ€˜Security Readerโ€™ role. This process could make life easier for admins, they simply need to add the Contoso admins to the newly created security group.

#####Step 7 Each admin account should confirm that โ€˜Fabrikam.comโ€™ appears in their list of organisations that they can collaborate with via this url: https://myaccount.microsoft.com/organizations

#####Step 8

Each โ€˜Contoso.comโ€™ admin must login to https;//mto.security.microsoft.com and select settings/ add tenants / and select โ€˜Fabrikam.comโ€™

To validate successful configuration and visibility of multi tenant devices. The Contoso admin needs to browse to the Devices \ Devices Inventory

By selecting Devices/ Tenants, it will provide an image that provides a high level overview of device status per tenant.

#####Step 9

In this scenario โ€˜Contoso.comโ€™ and โ€˜Fabrikam.comโ€™, corporate office locations have trusted named locations in Entra ID conditional access. When a โ€˜Contoso.comโ€™ admin accesses MTO, the Conditional access policies, may simply grant a โ€˜Contoso.comโ€™ admin access to โ€™Fabrikam.comโ€™ tenant without MFA challenge.

In the scenario where an organisation does not have โ€˜named locationsโ€™ configured in โ€˜Entra conditional accessโ€™, the source tenant admin, may be unable to view the organisations target tenant.

Browse to content distribution / tenant groups / create tenant group

In the bottom right hand corner, the image below may display and prompt for MFA login.

Once logged into Fabrikam , via MFA. The Fabrikam tenant will and devices will become visible in MTO

Also test login to the target tenant via https://security.microsoft.com/tenantid to ensure security admins can view all sections of the security.microsoft.com portal.

#####Step 10

MTO device filer view

#####Step 11

Advanced hunting.

Advanced hunting queries can be executed against โ€˜Contoso.comโ€™ and โ€˜Fabrikam.comโ€™

#Some sample KQL queries

## All mitre attack alerts

AlertInfo // Define timerange | where Timestamp > ago(30d) | where AttackTechniques != “” | mvexpand todynamic(AttackTechniques) | summarize count() by tostring(AttackTechniques) // Define graphic | render piechart

## Device Scans

DeviceEvents

| where ActionType == “AntivirusScanCompleted”

| summarize arg_max(Timestamp, *) by DeviceId

| extend ScanType = tostring(parse_json(AdditionalFields).ScanTypeIndex),

    DaysAgo = datetime_diff(‘day’, now(), Timestamp)

| project DeviceName, ActionType, ScanType, DaysAgo

// Filter only devices that have not performed a antivirus scan in the last day

| where DaysAgo > 0

| sort by DaysAgo

#####Summary

#Some of the positive features are:

– Simplified threat hunting with multi-tenancy support.

– Centralized view of all device inventory across all tenants and within each tenant.

– Instant insights and ability to filter views according to needs.

The most amazing feature for me is the ability to run KQL queries across all tenants. I ran some KQL queries across 8 tenants with thousands of devices and the results took between 1 โ€“ 5 seconds.

#One of the negative features is:

– The service does not provide a cross-tenant reporting functionality.

#### Reference for KQL queries.

https://github.com/Bert-JanP/Hunting-Queries-Detection-Rules/blob/main/MITRE%20ATT%26CK/Mapping.md