Skip to content
Audit Logging Prerequisites (M365 and Entra ID)

Audit Logging Prerequisites (M365 and Entra ID)

Hal automates everything it can, but two Microsoft-side capabilities need to be enabled in the customer’s tenant before sign-in and audit events can flow into Hal. Both are prerequisites Microsoft doesn’t expose via Graph API, so Hal can’t toggle them on your behalf — but Hal will detect when they’re missing and tell you in chat.

This page is what Hal links you to when it surfaces a remediation.


1. Unified Audit Logging in Exchange Online (M365 audit events)

What it does

Microsoft’s Office 365 Management Activity API — which feeds Hal the M365 audit logs (mailbox operations, admin changes, SharePoint events, DLP events) — is gated behind a per-tenant Exchange Online setting called Unified Audit Log Ingestion. When this is off, the API rejects every subscription start with a misleading error (“Tenant does not exist”) and Hal can’t pull a single event.

This setting is off by default for some Exchange Online deployments and on by default for others, depending on tenant age and earlier admin actions. There’s no way to detect from outside the tenant which state yours is in — you have to check.

How to check and enable

In PowerShell or Microsoft Cloud Shell, signed in as a Global Administrator for the customer’s tenant:

Connect-ExchangeOnline
Enable-OrganizationCustomization
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true

Notes:

  • Connect-ExchangeOnline opens a browser sign-in (or device-code prompt in Cloud Shell). Use the customer’s Global Admin account.
  • Enable-OrganizationCustomization rehydrates the tenant (see next sub-section) — required on dehydrated tenants before any Exchange admin command like Set-AdminAuditLogConfig will accept changes. Can take several minutes; if it returns “already enabled,” ignore it and continue.
  • Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true is the actual switch that turns UAL on.

What “dehydration” is and why it matters

A fresh Exchange Online tenant ships in a dehydrated state: Microsoft populates only the minimum config rows needed to operate the default-tier mailbox service, and admin commands that try to customize anything (admin audit settings, RBAC roles, retention policies, transport rules, etc.) fail or silently no-op because there’s no per-tenant config object to write into.

Enable-OrganizationCustomization switches the tenant from dehydrated to customized, allocating per-tenant config storage and unblocking every Exchange admin commandlet. Microsoft documents this at learn.microsoft.com → Enable-OrganizationCustomization.

Practically: if Set-AdminAuditLogConfig returns “this command isn’t available in your environment” or appears to succeed but Get-AdminAuditLogConfig shows the change didn’t stick, the tenant is dehydrated and Enable-OrganizationCustomization is the fix.

The command is idempotent and one-way — once a tenant is customized, it stays customized; running it on an already-customized tenant returns “This organization is already enabled for customization” and is otherwise a no-op. Safe to always include in the script regardless of state.

Verify it took

Get-AdminAuditLogConfig | Select-Object UnifiedAuditLogIngestionEnabled

Should return True. After this, ask Hal in chat:

Re-run verify_tenant_access for <client>

Hal will re-probe the Office 365 Management API and confirm subscription starts now succeed.

What Hal looks for

Internally, Hal probes POST /api/v1.0/<tenant>/activity/feed/subscriptions/start?contentType=Audit.AzureActiveDirectory with the per-tenant credentials. Three outcomes Hal maps to specific diagnostics:

  • 200 OK — UAL is on, subscription started or already running. ✅
  • 400 + AF20024 — subscription already running. ✅
  • 400 + "Tenant ... does not exist" — UAL is off. ❌ This page is the remediation Hal hands you.

2. Entra ID P1 license (Microsoft Graph sign-in logs)

What it does

Microsoft Graph’s /auditLogs/signIns endpoint — which feeds Hal the Entra ID sign-in events (interactive logins, MFA challenges, risk scores, conditional access results, impossible-travel signals, device posture data) — is license-gated behind Entra ID P1 (or higher).

P1 is bundled into:

  • Microsoft 365 Business Premium ($22/user/month)
  • Microsoft 365 E3 ($36/user/month)
  • Microsoft 365 E5 ($57/user/month)
  • Enterprise Mobility + Security E3 ($10.60/user/month — P1 only, no Office)

Without P1, the sign-in logs API returns an empty response (or, in some configurations, a license-required error). Hal flags this in diagnostics as signin_license_required or as an empty-but-200 response with a license hint.

How to check current licensing

In PowerShell, signed in as a Global Admin:

Connect-MgGraph -Scopes "Directory.Read.All"
Get-MgSubscribedSku |
  Where-Object { $_.SkuPartNumber -match "AAD_PREMIUM|ENTERPRISEPREMIUM|SPB|EMS" } |
  Select-Object SkuPartNumber, @{N='Available';E={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}}

Empty result = no P1-bearing SKU on the tenant.

Two remediation paths

If P1 is licensed but unassigned to any user (Available > 0): Assign it to the users generating sign-ins (or all users) via the Microsoft 365 admin center:

If P1 is not on the tenant at all: purchase it.

  • Path: https://admin.microsoft.com/Adminportal/Home#/catalog
  • Search “Entra ID P1” → buy at least one seat → assign per the step above.
  • Or upgrade an existing Business Standard subscription to Business Premium — typically the cheapest path if you already have an Office bundle.

What Hal looks for

Internally, Hal probes GET /auditLogs/signIns?$top=1 with the per-tenant credentials. Three outcomes:

  • 200 with events — license and permissions both good. ✅
  • 200 with empty array — license probably missing OR genuinely quiet tenant. Hal flags this as ambiguous and points here.
  • 403 + premium/license/tier wording — license definitely missing. ❌ This page is the remediation.
  • 403 without license wording — AuditLog.Read.All permission wasn’t fully consented during onboarding. Re-run connect_m365_tenant in chat to re-grant.

What you lose without P1

Hal still works for M365 audit and directory audit triage. You lose:

  • Sign-in event ingestion → can’t see who’s signing in from where
  • Risk scores, MFA challenge results, conditional access hits
  • Impossible-travel detection
  • Device posture data on sign-ins

Identity-side investigations are blind for that customer until P1 is licensed.


Questions? Contact us.