Microsoft Defender Provider
This driver lets you query the Microsoft Defender APIs.
Note
This provider supports multiple API endpoints for accessing Microsoft Defender data:
M365DGraph (Recommended): Uses the Microsoft Graph API with ThreatHunting permissions. This is the preferred and most modern API.
MDE/MDATP: Uses the Microsoft Defender for Endpoint API (formerly MDATP). This is the fallback option when M365DGraph is not available.
M365D (Deprecated): The Microsoft 365 Defender API was deprecated by Microsoft and is no longer supported. The M365D provider has been removed from MSTICPy. If you use the “M365D” provider name, it will automatically fall back to using the MDE API endpoints.
Many components in MSTICPy still use the old abbreviation MDATP (Microsoft Advanced Threat Protection) for backwards compatibility.
Defender Configuration
Creating a Client App for Microsoft Defender
Microsoft Defender APIs can be accessed in both application and delegated user contexts. Accessing Microsoft Defender APIs as an application requires either a client secret or certificate, while delegated user auth requires an interactive signin through a browser or via device code.
As such, the details on registering an Azure AD application for MS Defender are different for application and delegated user auth scenarios. Please see the above links for more information. Notably, delegated user auth scenarios do not require a application credential and thus is preferable.
For delegated user auth scenarios, ensure that the application has a “Mobile or Desktop Application” redirect URI configured as http://localhost. A redirect URI is not required for applications with their own credentials.
API permissions for the client application will require tenant admin consent. Ensure that the consented permissions are correct for the chosen data environment and auth scenario (application or delegated user):
API Name |
Permission |
Data Environment |
|---|---|---|
Microsoft Graph |
ThreatHunting.Read.All |
M365DGraph |
WindowsDefenderATP |
AdvancedQuery.Read |
MDE, MDATP |
Note
M365DGraph is the recommended data environment as it uses the modern Microsoft Graph API. The MDE/MDATP endpoints are maintained for backwards compatibility and as a fallback option.
The Microsoft 365 Defender API (M365D) was deprecated by Microsoft and is no longer supported. The M365D provider has been removed from MSTICPy. If you specify “M365D” as the provider name, it will automatically fall back to using MDE endpoints for backwards compatibility.
Once you have registered the application, you can use it to connect to the MS Defender API using your chosen data environment.
Defender Configuration in MSTICPy
You can store your connection details in msticpyconfig.yaml.
For more information on using and configuring msticpyconfig.yaml see msticpy Package Configuration and MSTICPy Settings Editor
The settings in the file should look like the following:
DataProviders:
...
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
TenantId: "TENANT ID"
UserName: "User Name"
Cloud: "global"
If connecting to the MS Defender 365 API using application auth, we strongly recommend storing the client secret value in Azure Key Vault. You can replace the text value with a referenced to a Key Vault secret using the MSTICPy configuration editor. See msticpy Settings Editor
Your configuration when using Key Vault should look like the following:
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
ClientSecret:
KeyVault:
TenantId: "TENANT ID"
You can create multiple instances of Defender settings by adding an instance suffix to the “MicrosoftDefender” section name.
MicrosoftDefender-Tenant1:
Args:
ClientId: "CLIENT ID"
ClientSecret:
KeyVault:
TenantId: "TENANT ID"
MicrosoftDefender-Tenant2:
Args:
ClientId: "CLIENT ID"
UserName: "USER NAME"
TenantId: "TENANT ID"
When using a certificate with a private key, the configuration should be:
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
TenantId: "TENANT ID"
Certificate: "Path to certificate"
PrivateKey: "Path to private key"
If connecting to the MS Defender 365 API using application auth, we strongly recommend using a secret on the private key and storing it in Azure Key Vault. You can replace the text value with a referenced to a Key Vault secret using the MSTICPy configuration editor. See msticpy Settings Editor.
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
TenantId: "TENANT ID"
PrivateKey: "Path to private key"
Certificate: "Path to certificate"
PrivateKeySecret:
KeyVault:
Delegated Authentication Configuration
Delegated authentication allows you to authenticate as a user (with user consent) rather than as an application. This means:
You don’t need to store client secrets or certificates
Authentication uses your user credentials
You benefit from your organization’s security policies (MFA, conditional access, etc.)
Permissions are granted based on your user account rather than an app registration
If your organization uses federated authentication (e.g., ADFS, Okta), the authentication flow will automatically redirect to your federated identity provider
To use delegated authentication with MS Defender, configure your settings to include a username but not a client secret or certificate:
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
TenantId: "TENANT ID"
UserName: "user@domain.com"
Cloud: "global"
The presence of a UserName field triggers delegated (user) authentication.
When you connect, the authentication flow will:
Contact your Microsoft Entra ID tenant
If your account uses federated authentication, automatically redirect to your organization’s identity provider
Prompt for user credentials and any required MFA
Return to Entra ID after successful authentication
Issue the token needed to access MS Defender APIs
Delegated Authentication with Multiple Tenants
If you work with multiple tenants:
MicrosoftDefender-TenantA:
Args:
ClientId: "CLIENT ID A"
TenantId: "TENANT ID A"
UserName: "user@tenantA.com"
Cloud: "global"
MicrosoftDefender-TenantB:
Args:
ClientId: "CLIENT ID B"
TenantId: "TENANT ID B"
UserName: "user@tenantB.com"
Cloud: "global"
Token Caching
By default, authentication tokens are cached in a file named token_cache.bin
in the current directory. You can specify a custom location:
MicrosoftDefender:
Args:
ClientId: "CLIENT ID"
TenantId: "TENANT ID"
UserName: "user@domain.com"
TokenCachePath: "/path/to/custom/token_cache.bin"
Cloud: "global"
Note
When using delegated authentication, ensure your app registration
has a “Mobile or Desktop Application” redirect URI configured as
http://localhost. This is required for the interactive authentication flow.
Loading a QueryProvider for Microsoft Defender
Recommended: Use M365DGraph
defender_prov = QueryProvider("M365DGraph")
Alternative: Use MDE (legacy/fallback)
mde_prov = QueryProvider("MDE")
You can also use the alias “MDATP” for backwards compatibility.
Note
The “M365D” provider name has been deprecated because the Microsoft 365 Defender API is no longer supported by Microsoft. If used, it will automatically fall back to MDE endpoints for backwards compatibility. We recommend using “M365DGraph” for new implementations.
Specifying the Defender Cloud Instance
If connecting to the Defender API to run queries there are a number of different endpoints you can connect to. Which one is most applicable will depend on your location and which cloud you are using.
For M365DGraph (Microsoft Graph API):
By default ‘https://graph.microsoft.com/’ is used. For government clouds, the appropriate Graph endpoint will be selected automatically based on the cloud parameter.
defender_prov = QueryProvider("M365DGraph", cloud="gcc")
For MDE (Defender for Endpoint API):
By default ‘https://api.securitycenter.microsoft.com/’ is used, but others can be specified either in your MSTICPy config file, or by passing in the name with the cloud keyword:
mde_prov = QueryProvider("MDE", cloud="gcc")
Cloud |
MDE Endpoint |
|---|---|
global |
|
uk |
|
us |
|
eu |
|
gcc |
|
gcc-high |
|
dod |
Note
M365DGraph uses Microsoft Graph endpoints which are automatically configured for government clouds. The above table applies only to MDE/MDATP endpoints.
Connecting to Microsoft Defender
The parameters required for connection to Defender can be passed in a number of ways. The simplest is to configure your settings in msticpyconfig. You can then just call connect with no parameters.
defender_prov.connect()
If you have configured multiple instances you must specify an instance name when you call connect.
defender_prov.connect(instance="Tenant2")
Using Delegated (User) Authentication
If you want to use delegated authentication for your application, you can specify this when you call connect. By default, this will attempt to use browser-based authentication, however you can also use device code authentication (needed if using Azure ML or environments without browser access) by setting auth_type to “device”.
# Browser-based authentication (default for delegated auth)
defender_prov.connect(delegated_auth=True)
# Or explicitly specify interactive authentication
defender_prov.connect(delegated_auth=True, auth_type="interactive")
# Device code authentication (useful in restricted environments)
defender_prov.connect(delegated_auth=True, auth_type="device")
When using browser-based authentication, a browser window will open for you to sign in. If your organization uses federated authentication (e.g., ADFS, Okta, etc.), you’ll be automatically redirected to your organization’s login page. After authenticating (which may include MFA), you’ll be redirected back and the connection will complete automatically.
For device code authentication, you’ll be presented with a code and URL. Open the URL in any browser (on any device), enter the code, and sign in.
Connecting with Delegated Auth Using Connection Parameters
You can also pass delegated authentication parameters directly:
defender_prov.connect(
tenant_id='your-tenant-id',
client_id='your-client-id',
username='user@domain.com',
auth_type='interactive' # or 'device'
)
Or as a connection string:
conn_str = (
"tenant_id='243bb6be-4136-4b64-9055-fb661594199a'; "
"client_id='a5b24e23-a96a-4472-b729-9e5310c83e20'; "
"username='user@domain.com'"
)
defender_prov.connect(conn_str, auth_type='interactive')
Note
The delegated_auth parameter is automatically set to True
when a username is provided, so you don’t need to specify it explicitly.
Connecting with Application Authentication (Client Secret or Certificate)
You can also pass connection parameters as keyword arguments or a connection string.
To specify connection parameters as keyword arguments in the function call, the required parameters are:
tenant_id – The tenant ID of the Defender workspace to connect to.
client_id – The ID of the application registered for MS Defender.
client_secret – The secret used by the application (for app authentication).
username – The username for delegated authentication (for user authentication).
The client_secret and username parameters are mutually exclusive.
ten_id = input('Tenant ID')
client_id = input('Client ID')
client_secret = input('Client Secret')
defender_prov = QueryProvider('M365DGraph')
defender_prov.connect(tenant_id=ten_id, client_id=client_id, client_secret=client_secret)
You can also specify these parameters as a connection string of the form:
“tenant_id=’my_tenant’; client_id=’my_appid’; client_secret=’my_secret’”
# The use of parentheses here is just to concatenate the strings
# inside the parentheses, to create a single string.
conn_str = (
"tenant_id='243bb6be-4136-4b64-9055-fb661594199a'; "
"client_id='a5b24e23-a96a-4472-b729-9e5310c83e20'; "
"client_secret='[PLACEHOLDER]'"
)
defender_prov.connect(conn_str)
Other Microsoft Defender Documentation
For examples of using the MS Defender provider, see the sample Microsoft Defender Notebook
Built-in data_acquisition/DataQueries:Queries for Microsoft Defender.