๐ Recipe ยท Entra ID & Identity
Find a User's Last Sign-In Activity via Microsoft Graph (without Entra ID P1)
Retrieve the most recent sign-in event for a user from audit logs when the tenant lacks Entra ID Premium licensing
Complexity
Intermediate
Impact
security + audit + identity + troubleshooting
Context
Why This Matters
Administrators frequently need to confirm when a user last signed in โ to investigate account compromise, validate whether a departing employee has been active, audit dormant accounts, or triage login complaints. The obvious answer is the signInActivity property on the user object in Microsoft Graph, but that property is gated behind an Entra ID Premium P1 or P2 license. Tenants on Microsoft 365 Business Basic/Standard/Premium (without the add-on) or Office 365 E1/E3 will receive an HTTP 403 โ Tenant is not a B2C tenant and doesn't have premium license error when querying it.
The good news: the auditLogs/signIns endpoint is available in all tenants and retains up to 30 days of sign-in events (7 days for tenants without Premium). This recipe shows how to fall back to audit logs to answer the same question, and how to interpret the result โ including common failure codes like 50057 (account disabled).
Run this recipe when: you need to know a user's last login, you're investigating a help-desk ticket ("why can't I sign in?"), or you're auditing account activity on a non-Premium tenant.
Expected Outcomes
- The user's most recent sign-in event (successful or failed) with timestamp, application, IP address, and location.
- The sign-in result โ including any failure reason and error code โ so you know whether the user actually got in.
- A reusable pattern for querying sign-in logs by user ID that works on any tenant, regardless of license tier.
- Clear next-step guidance (e.g., account is disabled โ offer to re-enable; repeated failures from unknown IP โ consider revoke sessions + password reset).
Risks & Considerations
Retention limits
The auditLogs/signIns endpoint only retains 30 days of data on Premium tenants and just 7 days on non-Premium tenants. If the user hasn't signed in recently, the log may be empty โ this does not mean they never signed in, just that it was outside the retention window.
Failed sign-ins are still sign-ins
The most recent event may be a failed attempt (disabled account, wrong password, MFA failure). Always check the status.errorCode and status.failureReason fields before concluding the user was active. A non-zero errorCode means the sign-in did not succeed.
Non-interactive sign-ins
The default signIns endpoint returns interactive sign-ins. Service principal sign-ins, token refreshes, and some background authentications appear in separate collections (nonInteractiveUserSignIns, servicePrincipalSignIns). For a complete picture, query those too.
Privacy and compliance
Sign-in logs contain IP addresses and geolocation โ treat this as personal data under GDPR/CCPA. Do not export or forward it outside approved IT channels without a documented reason.
Don't confuse this with mailbox activity
A user with no recent sign-ins may still be receiving email, calendar invites, etc. If you're evaluating whether an account is truly dormant, also check mailbox last-activity via the Exchange reports or Graph usage reports.
Required Permissions
| Permission | Why It's Needed |
|---|---|
| AuditLog.Read.All | Required to read sign-in events from /auditLogs/signIns |
| Directory.Read.All | Required to resolve a display name or UPN to a user object ID before querying logs |
| User.Read.All | Alternative to Directory.Read.All for looking up the user record |
The fastest way to get this done โ just ask Dex. Copy the prompt below and paste it into your Dex conversation.
For IT Admins
Paste into Dex CoAdmin