Detection
OAuth / workload-identity abuse detection
Four new detections shipped against OAuth and service-principal abuse: device-code phishing, credential-add persistence, vendor brand mimicry, and application-vs-delegated permission risk weighting.
Updated May 26, 2026 | 8 min
device_code_user_signin
Device-code OAuth flow used by user sign-in
Severity: HIGH · MITRE: T1528 + T1078.004
Why it matters: OAuth device authorization grant is designed for input-constrained devices and rarely originates from normal browser/desktop activity. Storm-2372 (Russian APT, Oct 2024) used it to phish access tokens — the victim is shown a legitimate-looking Microsoft device-code prompt and authorizes the attacker's session.
Fires when: A user (not a service principal) completes a successful sign-in with authenticationProtocol = "deviceCode".
Suppressed: None — device-code is rare enough that every instance is worth a look.
service_principal_credential_added
New credential added to existing service principal
Severity: HIGH / CRITICAL · MITRE: T1098.001
Why it matters: Storm-0558 / SolarWinds persistence pattern — attacker compromises an existing service account and adds a new client secret or certificate to maintain access. Diff-based detection fires regardless of whether Microsoft surfaced the change in directoryAudits.
Fires when: A new passwordCredential (secret) or keyCredential (certificate) appears on a service principal or application registration that already existed in the inventory.
Suppressed: Entities younger than 7 days (initial credentials are not an attack) and the tenant's own connector principal (we don't alert on ourselves).
unverified_publisher_brand_mimicry
Application impersonates vendor brand without verified publisher
Severity: HIGH · MITRE: T1528
Why it matters: Realistic consent-phishing pattern — attackers register an app named "Microsoft Outlook" or "DocuSign Login" and request OAuth consent. Legitimate vendors have a Microsoft-attested verifiedPublisher; phishing apps don't.
Fires when: Application display name contains a known vendor brand (Microsoft, Outlook, Adobe, DocuSign, Salesforce, Atlassian, Google, Okta, etc.) AND Microsoft has not attested a verified publisher. Display name is NFKD-normalized to catch accented mimicry like "Adobé".
Suppressed: Microsoft first-party SPNs (matched via app_owner_organization_id) and the tenant's own connector principal.
permission_risk_split
Permission risk scoring split by application vs delegated
Severity: N/A — scoring change, not a new rule · MITRE: T1098.001 / T1078.004
Why it matters: The same Microsoft Graph scope carries different blast radius depending on grant type. Application "Mail.Read" lets a service principal read every mailbox tenant-wide non-interactively. Delegated "Mail.Read" only acts as the signed-in user, bounded by Conditional Access. The previous single marker set scored both equally.
Fires when: No new alert — but existing rules that look at "high-risk permissions" now use a stricter application-permission list (adds Mail.Read, Files.Read.All, User.Read.All, full_access_as_app). Findings on app-permission grants of those scopes will rank higher.
Suppressed: N/A.
Operator actions
- Open /alerts and filter by category (device_code_user_signin, service_principal_credential_added, unverified_publisher_brand_mimicry). New alerts carry MITRE chips that link out to attack.mitre.org.
- For device-code alerts: confirm with the user that they intentionally completed a device-code authorization. If unexpected, revoke active sessions + refresh tokens for the identity, and review consent grants on the targeted application.
- For credential-add alerts: confirm with the application owner that the secret addition was authorized. If unauthorized, revoke the credential, rotate all other secrets on the same identity, and review recent sign-in activity for that SP.
- For brand-mimicry alerts: check the linked application registration on /applications. If it impersonates a vendor without a verified publisher, revoke OAuth consent and disable the application.
- For permission scoring shifts: existing alerts on workload identities may move up the priority board. No action required — the scoring update is mechanical.
Scope and limits
- Device-code detection requires the beta /auditLogs/signIns endpoint (authenticationProtocol field is not yet in v1.0). Switched to beta on 2026-05-26 as a hotfix.
- Credential-add detection persists per-keyId fingerprints in applications_inventory and service_principals_inventory. On the first scan after deploy, every existing keyId is captured with first_seen_at = now and the 7-day entity-age gate suppresses any false-positive burst.
- Brand-mimicry detection ships with a curated list of ~17 vendor brands. Add more in services/detection_evaluator.py:_VENDOR_BRAND_MARKERS when you observe new mimicry patterns in the wild.
- These four detections are Microsoft-only at launch. Okta does not expose authenticationProtocol the same way, and Okta application catalog ingestion is deferred (Phase D).