tool

Script-GraphACCSignIn

·3 min read

Repository

graph_signins.py python script

Overview

Microsoft Graph User Sign-in Audit Tool is a Python utility for SOC analysts, incident responders and Entra ID admins. It pulls the authentication events of one account from the Microsoft Graph API (/auditLogs/signIns) using interactive PKCE login, exports a CSV report and builds a self-contained HTML dashboard.

Key features

  • No app registration needed: uses the public Microsoft Azure CLI client ID (04b07795-8ddb-461a-bbee-02f9e1bf7b46) with browser-based PKCE login.
  • Account picker forced (prompt="select_account") to switch between analyst identities easily.
  • Email normalization: trims spaces and lowercases the target user for accurate OData queries.
  • Custom time window with -d / --days (default: last 15 days).
  • Automatic pagination following @odata.nextLink until every log is collected.
  • Error code translation: common Entra ID codes (50126, 50053, 53003…) turned into readable explanations.
  • Two console modes: quiet progress bars by default, or event-by-event colored output with -v.
  • CSV export (UTF-8-BOM) and an interactive HTML dashboard with live search and All / Success / Failures filters.
  • Corporate proxy ready: works behind SSL/TLS inspection.

How it works

  1. Authentication: MSAL creates a PublicClientApplication and requests AuditLog.Read.All; your browser opens to sign in and complete MFA.
  2. Query: a UTC cutoff is calculated from the day offset and an OData filter is built.
  3. Retrieval: GET requests to https://graph.microsoft.com/v1.0/auditLogs/signIns, paginating while @odata.nextLink exists.
  4. Parsing: date, app, IP and location, OS and browser, status with error explanation and Conditional Access results.
  5. Reports: summary in the console plus .csv and .html files.
text
userPrincipalName eq '<user>' and createdDateTime ge <UTC_DATE>

Requirements

  • Python 3.8+ (standard Python or Anaconda).
  • Libraries: msal, requests, urllib3.
  • Microsoft Entra ID P1 or P2 (or Microsoft 365 E3/E5).
  • Delegated permission: AuditLog.Read.All.

The analyst account must have one of these roles:

  • Security Reader (recommended for SOC analysts)
  • Reports Reader
  • Global Reader
  • Security Administrator
  • Global Administrator

Installation

bash
pip install msal requests urllib3

With Anaconda: conda install requests and then pip install msal urllib3.

Usage

bash
# Default: last 15 days, quiet progress mode
python graph_signins.py -u user@company.com

# Custom time window
python graph_signins.py -u user@company.com -d 7
python graph_signins.py -u user@company.com -d 30

# Verbose, event by event
python graph_signins.py -u user@company.com -d 30 -v
ArgumentDefaultRequiredDescription
-u, --user—YesTarget UserPrincipalName or email.
-d, --days15NoNumber of past days to inspect.
-v, --verboseFalseNoEvent-by-event output in the terminal.

Outputs

text
=====================================================================================
 SIGN-IN EVENTS SUMMARY (15 DAYS) | UNIQUE IPs CHECKED: 3
=====================================================================================
 Total Logins   : 25
 Successful     : 23
 Failed         : 2
 Unique IPs     : 3
=====================================================================================
  • signins_<user>_<days>d_<timestamp>.csv — full export for Excel or a SIEM (date, user, app, status, error code and meaning, IP, location, OS, browser, Conditional Access).
  • signins_<user>_<days>d_<timestamp>.html — standalone dashboard with metric cards, instant search, one-click filters and error explanations.

Corporate proxy & SSL

Behind a corporate proxy doing SSL/TLS inspection, Python HTTPS calls can fail with CERTIFICATE_VERIFY_FAILED. The script handles it by silencing urllib3 warnings and using verify=False on outbound requests:

python
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

requests.get(url, headers=headers, verify=False)

View on GitHub ↗