Back to BEC Investigation

OAuth Audit

CLIdfir-cli bec oauth-audit

Audit 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

FlagTypeDescription
--userstringAudit grants for a specific user (UPN or object ID)
--tenant-wideboolAudit all OAuth grants across the entire tenant
--risk-onlyboolOnly display grants that exceed the risk threshold
--permissions-filterstringComma-separated list of permissions to filter on (e.g. Mail.Read,Files.ReadWrite)
--min-risk-scoreintMinimum risk score to include in results (0-100, default: 0)
--show-revocationboolInclude PowerShell and Graph API revocation commands in output
--client-idstringFilter results to a specific OAuth application client ID
--risk-thresholdstringMinimum 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-revocation is 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.All and Directory.Read.All permissions on your Azure AD app registration.
  • Tenant-wide scans may take longer in large tenants. Use --user to scope the audit to a specific compromised account.