Back to BEC Investigation
OAuth Audit
CLI
dfir-cli bec oauth-auditAudit OAuth and consent grants across your Microsoft 365 tenant for malicious or over-privileged applications. Includes publisher verification, LOB/same-tenant detection, delegated vs application consent scoring, and revocation guidance with PowerShell and Graph API commands.
Data Source
Direct Microsoft Graph
API Credits
None (direct Graph)
Permissions
Application.Read.All, Directory.Read.All
Auth
Azure AD app registration
CLI Usage
Tenant-wide scan
dfir-cli bec oauth-audit --tenant-wide
Per-user (risky only)
dfir-cli bec oauth-audit --user compromised@contoso.com --risk-only
Filtered with revocation commands
dfir-cli bec oauth-audit --tenant-wide \ --permissions-filter "Mail.Read,Files.ReadWrite" \ --min-risk-score 60 --show-revocation
Flags
| Flag | Type | Description |
|---|---|---|
| --user | string | Audit grants for a specific user (UPN or object ID) |
| --tenant-wide | bool | Audit all OAuth grants across the entire tenant |
| --risk-only | bool | Only display grants that exceed the risk threshold |
| --permissions-filter | string | Comma-separated list of permissions to filter on (e.g. Mail.Read,Files.ReadWrite) |
| --min-risk-score | int | Minimum risk score to include in results (0-100, default: 0) |
| --show-revocation | bool | Include PowerShell and Graph API revocation commands in output |
| --client-id | string | Filter results to a specific OAuth application client ID |
| --risk-threshold | string | Minimum risk level to display (none, low, medium, high, critical) |
Example Output
{
"data": [
{
"app_id": "07fce198-e5a7-487a-a38a-256386175cea",
"app_name": "O365 Backup Tool",
"publisher": "",
"publisher_verified": false,
"consent_type": "application",
"permissions": [
"Mail.Read",
"Files.Read.All",
"User.Read.All",
"Calendars.Read"
],
"risk_score": 65,
"risk_level": "high",
"risk_factors": [
{
"category": "publisher",
"description": "Unverified publisher (third-party app)",
"score": 15
},
{
"category": "permission",
"description": "High-risk permission: Mail.Read",
"score": 20
},
{
"category": "redirect_uri",
"description": "Suspicious redirect URI: https://o365backup-tool.herokuapp.com/auth",
"score": 20
},
{
"category": "age",
"description": "App created within the last 7 days",
"score": 10
}
],
"is_active": true,
"consented_date_time": "2026-04-08T20:41:18Z",
"redirect_uris": [
"https://o365backup-tool.herokuapp.com/auth"
],
"credential_count": 0,
"revocation": {
"steps": [
"1. Review the app's application permissions and redirect URIs",
"2. Check audit logs for admin consent activity",
"3. Remove the app: Azure Portal > App registrations > O365 Backup Tool > Delete"
],
"powershell_command": "Remove-MgApplication -ApplicationId 1a68a2f9-b52a-4b6d-9b36-04dbe598d0b1",
"graph_api_call": "DELETE /applications/1a68a2f9-b52a-4b6d-9b36-04dbe598d0b1"
}
}
],
"meta": {
"total_grants": 7,
"risky_grants": 7,
"by_consent_type": { "application": 6, "delegated": 1 },
"critical": 3,
"high": 4,
"medium": 0,
"low": 0,
"none": 0
}
}Key Features
- LOB / same-tenant detection — automatically identifies line-of-business and in-house applications and skips the unverified publisher penalty for apps registered in the same tenant.
- Consent type scoring — differentiates between delegated consent (user-level) and application consent (admin-level), weighting application consent higher in the risk model.
- Revocation guidance — when
--show-revocationis enabled, each risky grant includes ready-to-run PowerShell and Graph API commands for immediate remediation. - Permission analysis — flags dangerous permission combinations such as Mail.Send + Mail.ReadWrite, Files.ReadWrite.All, and full directory access.
Important Notes
- This command queries Microsoft Graph directly — no DFIR platform API credits are consumed.
- Requires
Application.Read.AllandDirectory.Read.Allpermissions on your Azure AD app registration. - Tenant-wide scans may take longer in large tenants. Use
--userto scope the audit to a specific compromised account.