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:

  1. Contact your Microsoft Entra ID tenant

  2. If your account uses federated authentication, automatically redirect to your organization’s identity provider

  3. Prompt for user credentials and any required MFA

  4. Return to Entra ID after successful authentication

  5. 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

https://api.securitycenter.microsoft.com/

uk

https://api-uk.securitycenter.microsoft.com/

us

https://api-us.securitycenter.microsoft.com/

eu

https://api-eu.securitycenter.microsoft.com/

gcc

https://api-gcc.securitycenter.microsoft.us/

gcc-high

https://api-gov.securitycenter.microsoft.us/

dod

https://api-gov.securitycenter.microsoft.us/

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<https://github.com/microsoft/msticpy/blob/master/docs/notebooks/MDATPQuery.ipynb>`__

Built-in data_acquisition/DataQueries:Queries for Microsoft Defender.

Microsoft Defender driver API documentation