How to Collect Azure AD Sign-In Logs | Microsoft Graph API Tutorial
3 minute read
Overview
Azure AD sign-in logs capture every user authentication event in your Microsoft 365 and Azure environment. Use this guide to collect sign-in data for security monitoring, compliance reporting, and detecting authentication anomalies like failed logins or risky sign-ins.
Common Use Cases:
- Detect failed authentication attempts and brute force attacks
- Monitor risky sign-ins flagged by Azure AD Identity Protection
- Track user login patterns and geographic anomalies
- Generate compliance reports for authentication activity
Prerequisites
Before configuring Edge Delta, complete the Azure AD application setup:
- Register an Azure AD application with Application permissions (not Delegated)
- Grant the
AuditLog.Read.Allpermission and obtain admin consent - Create a client secret and note your Tenant ID, Client ID, and Client Secret
For detailed setup instructions, see Microsoft Graph API Integration.
Configuration
Basic Sign-In Logs Collection
nodes:
- name: azure_ad_signin_logs
type: http_pull_input
endpoint: https://graph.microsoft.com/v1.0/auditLogs/signIns
method: GET
pull_interval: 5m
authorization:
strategy: oauth_client_credentials
client_credentials:
token_url: https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
client_id: YOUR_CLIENT_ID
client_secret: YOUR_CLIENT_SECRET
scopes:
- https://graph.microsoft.com/.default
header_templates:
- header: Authorization
value: Bearer $ACCESS_TOKEN
parameters:
- name: "$orderby"
value: "createdDateTime asc"
- name: "$top"
value: "50"
parameter_expressions:
- name: "$filter"
value_expression: Concat(["createdDateTime ge ", FormatTime(Now() - Duration("5m10s"), "%Y-%m-%dT%H:%M:%SZ")], "")
Monitor Failed Sign-Ins Only
Filter for failed authentication attempts to detect potential attacks:
nodes:
- name: failed_signin_monitor
type: http_pull_input
endpoint: https://graph.microsoft.com/v1.0/auditLogs/signIns
method: GET
pull_interval: 5m
authorization:
strategy: oauth_client_credentials
client_credentials:
token_url: https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
client_id: YOUR_CLIENT_ID
client_secret: YOUR_CLIENT_SECRET
scopes:
- https://graph.microsoft.com/.default
header_templates:
- header: Authorization
value: Bearer $ACCESS_TOKEN
parameters:
- name: "$orderby"
value: "createdDateTime asc"
- name: "$top"
value: "100"
- name: "$filter"
value: "status/errorCode ne 0"
Monitor High-Risk Sign-Ins
Capture sign-ins flagged by Azure AD Identity Protection:
nodes:
- name: risky_signin_monitor
type: http_pull_input
endpoint: https://graph.microsoft.com/v1.0/auditLogs/signIns
method: GET
pull_interval: 5m
authorization:
strategy: oauth_client_credentials
client_credentials:
token_url: https://login.microsoftonline.com/YOUR_TENANT_ID/oauth2/v2.0/token
client_id: YOUR_CLIENT_ID
client_secret: YOUR_CLIENT_SECRET
scopes:
- https://graph.microsoft.com/.default
header_templates:
- header: Authorization
value: Bearer $ACCESS_TOKEN
parameters:
- name: "$orderby"
value: "createdDateTime asc"
- name: "$top"
value: "50"
- name: "$filter"
value: "riskLevelAggregated eq 'high' or riskLevelAggregated eq 'medium'"
OData Filter Examples
Use these filters in the $filter parameter to narrow results:
| Filter | Description |
|---|---|
status/errorCode eq 0 | Successful sign-ins only |
status/errorCode ne 0 | Failed sign-ins only |
riskLevelAggregated eq 'high' | High-risk sign-ins |
appDisplayName eq 'Microsoft 365' | Specific application |
startswith(userPrincipalName, 'admin') | Admin user sign-ins |
location/countryOrRegion eq 'US' | Sign-ins from specific country |
Combine multiple conditions:
$filter: "status/errorCode ne 0 and createdDateTime ge 2024-01-01T00:00:00Z"
Sample Sign-In Log
{
"id": "SignIn_EFGH5678_20240101_001",
"createdDateTime": "2024-01-01T10:05:00Z",
"userPrincipalName": "john.doe@company.com",
"userDisplayName": "John Doe",
"appDisplayName": "Microsoft 365",
"status": {
"errorCode": 0,
"failureReason": null,
"additionalDetails": "MFA completed successfully"
},
"location": {
"city": "Seattle",
"state": "Washington",
"countryOrRegion": "US"
},
"deviceDetail": {
"browser": "Chrome 120.0.0.0",
"operatingSystem": "Windows 11"
},
"riskLevelAggregated": "low",
"conditionalAccessStatus": "success"
}
Key Fields for Analysis
| Field | Description | Use Case |
|---|---|---|
status.errorCode | 0 = success, non-zero = failure | Detect failed logins |
riskLevelAggregated | none, low, medium, high, hidden | Identity Protection alerts |
location.countryOrRegion | Geographic location | Detect anomalous locations |
conditionalAccessStatus | success, failure, notApplied | Conditional Access monitoring |
deviceDetail.browser | Browser information | Device fingerprinting |
Troubleshooting
| Issue | Solution |
|---|---|
| 401 Unauthorized | Verify tenant ID, client ID, and secret are correct |
| 403 Forbidden | Ensure AuditLog.Read.All permission has admin consent |
| Empty results | Sign-in logs may have 2-5 minute processing delay |
| Missing fields | Some fields require Azure AD Premium P1/P2 license |
Related Pages
- Microsoft Graph API Overview - Complete API reference
- Azure AD Directory Audit Logs - Admin action monitoring
- Microsoft Security Alerts - Defender security events