In the Microsoft Entra admin center, open Identity → Monitoring & health → Sign-in logs, set your filters, and choose Download → JSON. For bigger or scripted pulls, use Microsoft Graph: GET /auditLogs/signIns. Either way, you only get what’s still retained: 7 days on Entra ID Free, 30 days with P1 or P2.
Sign-in logs show who authenticated, from where, to which app, and whether MFA and Conditional Access held. In identity-driven attacks, that’s most of the story. Prime Core has 170 detection rules for Entra ID sign-in data, mapped to 113 MITRE ATT&CK techniques. Among them: password spraying (T1110.003), MFA fatigue (T1621) and logins with stolen cloud credentials (T1078.004).
Before you start
Retention is short. If the activity you’re after is older than 7 or 30 days, the portal and Graph won’t have it. The only place it might still exist is wherever your diagnostic settings send sign-in logs: a Log Analytics workspace, Microsoft Sentinel or a storage account. See our [Microsoft Sentinel export guide] for that route.
Roles. Reports Reader is the least-privileged role that can read sign-in logs. Security Reader and Global Reader work too.
There are four kinds of sign-ins. Interactive user, non-interactive user, service principal and managed identity each have their own tab in the portal. Token replay and abuse of refresh tokens tend to show up under non-interactive, which people forget to export.
Option 1: Download from the portal
- Go to Sign-in logs and pick the tab (start with interactive, then non-interactive).
- Set Date and any filters (user, application, status).
- Choose Download, then JSON.
The portal limits how many records a single download includes. [PROOF: confirm the current limit.] For large ranges, split by day or use Graph.
Option 2: Microsoft Graph PowerShell
This pulls raw API JSON, follows paging, and writes one sign-in per line:
Connect-MgGraph -Scopes "AuditLog.Read.All"
$uri = "https://graph.microsoft.com/v1.0/auditLogs/signIns?`$filter=createdDateTime ge 2026-10-19T00:00:00Z and createdDateTime lt 2026-10-20T00:00:00Z"
do {
$page = Invoke-MgGraphRequest -Method GET -Uri $uri -OutputType Json | ConvertFrom-Json
$page.value | ForEach-Object { $_ | ConvertTo-Json -Depth 10 -Compress } | Add-Content signins_1019.jsonl
$uri = $page.'@odata.nextLink'
} while ($uri)
The v1.0 endpoint returns interactive sign-ins. Non-interactive and service principal sign-ins need the beta endpoint with a signInEventTypes filter. Reading sign-ins through the API also depends on your tenant’s license tier.
Timestamps are UTC throughout.
What to look for
| Field or value | What it tells you |
|---|---|
| status.errorCode 50126 | Wrong username or password. Many of these across many users means spraying |
| status.errorCode 50053 | Account locked by smart lockout |
| status.errorCode 500121 | MFA failed or was denied; a burst of these is MFA fatigue |
| clientAppUsed = IMAP, POP, SMTP, “Other clients” | Legacy authentication that skips MFA |
| conditionalAccessStatus | Whether CA applied, passed or failed |
| riskLevelDuringSignIn, location, ipAddress | Risky or unfamiliar origins |
The pattern worth stopping for: a string of 50126 failures across many accounts from one IP range, then a success for one of them.
Upload, sanitize and review in LogTotal
- Upload. Open logtotal.com and drop in the JSON file.
- Sanitize. [what gets masked: UPNs, display names, IPs, device names, tenant and object IDs]. Look it over before you continue.
- Review.
When it goes wrong
| Symptom | Likely cause | Fix |
|---|---|---|
| Nothing older than a week or a month | Retention for your license tier | Check Log Analytics, Sentinel or storage if diagnostic settings were on |
| Graph returns 403 | Missing AuditLog.Read.All consent, role or license | Grant consent; check your role and tenant license |
| Export has only interactive sign-ins | Other types live in separate tabs, or in beta Graph | Export each tab; use the beta endpoint |
| Download contains fewer records than the portal shows | Portal download limit | Split by day, or use Graph |
FAQ
What about Entra audit logs?
Those are a different log: directory changes like new users, role assignments and app consents. Same portal area, Audit logs. In Graph it’s /auditLogs/directoryAudits. In an incident, you usually want both.
Can I get sign-ins from Sentinel instead?
Yes, if the Entra ID connector is on: they’re in the SigninLogs and AADNonInteractiveUserSignInLogs tables, with whatever retention your workspace has.