Microsoft Defender for Endpoint
Pulls incidents, alerts, and device-posture signals from Microsoft Graph's unified security surface (including advanced hunting), deriving KRIs for onboarding gaps, high-severity incidents, critical missing patches, ASR violations, tamper-protection health, stale devices, and unresolved malware dwell time.
At a glance
| Vendor | Microsoft Defender for Endpoint (part of Microsoft 365 Defender) |
|---|---|
| Source type | edr |
| Vendor ID (slug) | defender-for-endpoint |
| Base URL | https://graph.microsoft.com/v1.0 — commercial cloud. US Gov / China / Germany customers override this manually. |
| Auth method | oauth2 — client-credentials flow. Draxis mints an Authorization: Bearer <access_token> per run against https://login.microsoftonline.com/<tenant_id>/oauth2/v2.0/token. |
| Schedule default | daily — override to hourly for tighter response on incident and malware KRIs. |
| Licensing | Defender for Endpoint Plan 1 or Plan 2. All seven KRIs require a tenant onboarded to MDE — the per-device KRIs run against the advanced-hunting tables (DeviceInfo, DeviceTvm*, DeviceEvents) which only populate for MDE tenants. Plan 2 is required for advanced hunting on TVM tables (missing patches, tamper protection). |
| Availability | New in 2026.04. |
Required scopes & roles
Draxis authenticates as an Entra ID app registration using the client-credentials flow — no user is impersonated. All KRIs are derived from Microsoft Graph, which means exactly three Application permissions (all Read.All, all requiring admin consent):
SecurityIncident.Read.All— list incidents with severity and status. BacksGET /security/incidents. Used for the high-severity-open-incidents KRI.SecurityAlert.Read.All— list unified (alerts_v2) security alerts. BacksGET /security/alerts_v2. Used for the unresolved-malware-dwell KRI.ThreatHunting.Read.All— run advanced-hunting KQL queries against Defender telemetry tables. BacksPOST /security/runHuntingQuery. Used for the five device-posture KRIs (onboarding, stale devices, tamper protection, missing patches, ASR violations).
Do not grant the app any ReadWrite.All variant, Global Administrator, or Security Administrator role membership. Draxis never writes to incidents, alerts, or Defender config.
Setup steps
- Register the app. In the Entra admin center go to Identity → Applications → App registrations → New registration. Name it
Draxis Defender Reader. Supported account types: Single tenant. Redirect URI: leave blank. Click Register. - Copy the two IDs you’ll need from the app's Overview page:
- Application (client) ID — you’ll paste this into Draxis’s Client ID field.
- Directory (tenant) ID — you’ll paste this into Draxis’s Extra Config JSON.
- Create a client secret. Go to Certificates & secrets → Client secrets → New client secret. Name it
draxis-connector, pick a rotation window that matches your policy (Microsoft caps at 24 months), and copy the secret Value — not the Secret ID. You can’t retrieve this value later; if you lose it, create a new secret. - Add the Graph permissions. Go to API permissions → Add a permission → Microsoft Graph → Application permissions. Search for and add each of these three permissions exactly:
Do not add the Delegated variants — client-credentials flows can only use Application permissions.SecurityIncident.Read.All SecurityAlert.Read.All ThreatHunting.Read.All - Grant admin consent. Back on the API permissions page, click Grant admin consent for <your tenant>. The status column should flip to green checkmarks for all three. If the button is disabled, ask a Global Administrator or Privileged Role Administrator to perform the consent.
- (Optional) Restrict by IP. Under Authentication → Conditional Access on the app, require requests to come from your corporate network or from the Draxis egress range. Skip this on first setup and add it after you’ve confirmed the connector works.
Wire it into Draxis
- Open Settings → Integrations in your tenant.
- Click Add integration and pick Endpoint Detection & Response as the source type.
- Pick Microsoft Defender for Endpoint (M365 Defender) from the vendor dropdown. Draxis auto-fills the Graph base URL, the OAuth auth method, the daily schedule, and seeds
extra_config_jsonwith{"tenant_id":""}. - In Client ID, paste the Application (client) ID from step 2.
- In Client Secret, paste the secret Value from step 3. Draxis encrypts it server-side with
encryption.keybefore storage. - In the Extra Config JSON field, replace the empty
tenant_idwith your Directory (tenant) ID from step 2, e.g.{"tenant_id":"00000000-0000-0000-0000-000000000000"}. - Click Test. Green means Draxis exchanged the credentials for an access token and listed an incident record successfully.
- Under KRIs to import, tick the KRIs you want Draxis to manage. All seven
mde_*KRIs are checked by default; uncheck any you don’t need (for instance, a Plan 1 tenant will want to uncheck the TVM-dependent KRIs — see Quirks). Selected rows are created on save with the seeded thresholds. Unchecking a previously-imported KRI deletes it on save. - Save. The connector runs
dailyby default; use Run now from run history to trigger the first sync immediately.
KRIs produced
| Slug | Meaning | Derivation |
|---|---|---|
mde_devices_not_onboarded |
Count of devices Defender sees but that are not fully onboarded | Advanced-hunting KQL: DeviceInfo | where Timestamp > ago(7d) | summarize arg_max(Timestamp, OnboardingStatus) by DeviceId | where OnboardingStatus != "Onboarded" | count |
mde_incidents_high_open |
Open (non-resolved) incidents with severity high — Graph’s top tier |
GET /security/incidents?$filter=severity eq 'high' and status ne 'resolved', count the returned page (Graph caps severity at high; it has no critical enum value) |
mde_critical_missing_patches |
Distinct devices with at least one critical software vulnerability | Advanced-hunting KQL: DeviceTvmSoftwareVulnerabilities | where VulnerabilitySeverityLevel == "Critical" | summarize dcount(DeviceId) |
mde_asr_rule_violations_24h |
Attack-surface-reduction rules that blocked activity in the last 24h | Advanced-hunting KQL: DeviceEvents | where Timestamp > ago(24h) | where ActionType startswith "Asr" and ActionType endswith "Blocked" | count |
mde_tamper_protection_disabled |
Distinct devices non-compliant with the tamper-protection secure-config item | Advanced-hunting KQL: DeviceTvmSecureConfigurationAssessment | where ConfigurationId == "scid-2011" | where IsApplicable == 1 | where IsCompliant == 0 | summarize dcount(DeviceId) |
mde_devices_stale_7d |
Devices whose latest DeviceInfo telemetry is older than 7 days |
Advanced-hunting KQL: DeviceInfo | summarize LastSeen = max(Timestamp) by DeviceId | where LastSeen < ago(7d) | count |
mde_malware_unresolved_24h_plus |
Open malware alerts that have been unresolved for more than 24 hours | GET /security/alerts_v2?$filter=category eq 'Malware' and status ne 'resolved' and createdDateTime lt <now-24h>, count the returned page |
Each row is a slug the connector writes to. Draxis creates the matching kri rows automatically when you check them in the KRIs to import section of the integration form — no manual API call or seed script needed. Thresholds shown in the table are the seeded defaults; you can edit them freely in the KRIs tab afterwards.
Vendor quirks
- Graph incidents cap at
severity = 'high'. Unlike the legacy MDE portal, Graph's/security/incidentshas nocriticalenum value — its severity ladder isinformational | low | medium | high. The KRI slug ismde_incidents_high_opento match what the API actually returns. If you were hoping to split high vs. critical, configure distinct thresholds on the same value instead. - Advanced hunting requires tables that only exist on MDE tenants.
DeviceInfo,DeviceEvents, and theDeviceTvm*family are populated only for devices onboarded to Defender for Endpoint. A tenant running only Defender for Office 365 (email/identity) will see the hunting queries return zero with no error — the connector logs awarnper failed hunting KRI and still writes the incident/alert KRIs that didn’t depend on hunting. - TVM tables require Plan 2.
DeviceTvmSoftwareVulnerabilitiesandDeviceTvmSecureConfigurationAssessmentare Threat & Vulnerability Management tables — they populate only for Defender for Endpoint Plan 2. On a Plan 1 tenant the missing-patches and tamper-protection KRIs record as 0; switch to P2 to light them up. - ASR KRI is a count of events, not devices. A single misconfigured endpoint can drive this number high on its own if it’s constantly tripping the same rule. Pair the threshold with the stale-devices or onboarding KRI to catch that case.
- Tamper protection is keyed on
scid-2011. Microsoft occasionally renumbers secure-configuration items; if that ID stops matching, this KRI will go to 0 without erroring. Our quarterly smoke test catches these changes — open a support ticket if you see it flatline after a Microsoft portal redesign. - Hunting rate limits are real. Graph caps advanced hunting at 45 calls per minute per app-tenant pair and 1000 calls per day. With five hunting KRIs per run on a daily schedule this is nowhere close to the limit, but if you drop the schedule to minutely across many tenants you’ll hit it. Stay at daily or hourly.
- Client secrets expire. Microsoft caps client-secret lifetime at 24 months. When it expires, every run fails with 401 at token exchange — the Entra portal will not warn you. Schedule a rotation in your calendar.
- Non-commercial clouds. For US Government, China (21Vianet), or Germany, override the Graph base URL to the correct sovereign endpoint before saving. The token endpoint also differs; the connector currently assumes
login.microsoftonline.com— support sovereign clouds via a feature request if you need it.
Troubleshooting
- HTTP 401 on Test with
invalid_client— the client secret is wrong (you copied the Secret ID instead of the Value) or has expired. Generate a new secret and update Draxis. - HTTP 401 on Test with
AADSTS90002— the tenant ID in Extra Config is wrong. Copy the Directory (tenant) ID from the app registration’s Overview page. - HTTP 403 with
Insufficient privileges— a Graph permission is missing or admin consent hasn’t been granted. Re-open API permissions and confirm all three are green-checked. - Hunting KRIs all record as 0 but incident/alert KRIs look correct — the tenant isn’t onboarded to Defender for Endpoint, or the onboarded devices haven't emitted enough telemetry yet. The run log will include one
warnline per failed hunting query explaining why (typically a400stating the table doesn’t exist). mde_critical_missing_patchesandmde_tamper_protection_disabledare 0 but other hunting KRIs work — tenant is on Plan 1, not Plan 2. The TVM tables require P2 licensing.rowsSkipped > 0androwsWritten = 0— your tenant hasn’t imported any KRIs for this integration yet. Open the integration in Settings → Integrations, tick the KRIs under KRIs to import, and save.- Still stuck? Open a support ticket with the run ID (from Run history) and we’ll dig in.