--- name: authentication-tracing description: Use this skill when asked to trace authentication flows, analyze SessionId chains, investigate token reuse vs interactive MFA, or assess geographic anomalies in sign-ins. Triggers on keywords like "trace authentication", "trace back to interactive MFA", "SessionId analysis", "token reuse", "geographic anomaly", "impossible travel", or when investigating suspicious sign-in locations. This skill provides forensic analysis of Entra ID authentication chains to distinguish legitimate activity from credential/token theft. threat_pulse_domains: [identity] drill_down_prompt: 'Trace authentication chain for {entity} — SessionId analysis, token reuse, geographic anomalies' --- # Authentication Tracing - Instructions ## Purpose This skill performs forensic analysis of Entra ID authentication flows to determine whether anomalous sign-ins represent: - **Legitimate activity** (VPN usage, user travel, mobile carrier routing) - **Token theft/credential compromise** (stolen refresh tokens, session hijacking) The key distinction is whether the user **actively performed MFA** at a suspicious location or if the authentication used a **refresh token from a prior session**. --- ## 📑 TABLE OF CONTENTS 1. **[Critical Workflow Rules](#-critical-workflow-rules---read-first-)** - Start here! 2. **[Key Forensic Indicators](#key-forensic-indicators)** - Understanding authentication signals 3. **[IP Enrichment Data](#ip-enrichment-data-structure-primary-evidence-source)** - JSON structure reference 4. **[6-Step Forensic Workflow](#forensic-workflow-tracing-authentication-chains)** - SessionId-based investigation 5. **[Real-World Example](#real-world-example-geographic-anomaly-analysis)** - Complete walkthrough 6. **[Authentication Methods Reference](#common-authentication-methods-and-requestsequence-patterns)** - Method patterns 7. **[Risk Escalation Criteria](#when-to-escalate-authentication-anomalies)** - High/Medium/Low classification 8. **[Best Practices](#best-practices-for-authentication-tracing)** - Summary checklist --- ## ⚠️ CRITICAL WORKFLOW RULES - READ FIRST ⚠️ **🚨 MANDATORY CHECKPOINT: Before providing ANY risk assessment for authentication anomalies:** 1. **STOP** - Do not improvise or use general security knowledge 2. **READ** the complete risk assessment framework in this document 3. **QUOTE** specific instruction sections in your analysis 4. **VERIFY** your conclusions match documented guidance before responding to user **Before executing ANY authentication tracing queries, you MUST:** 1. **Read the SessionId-based workflow** (Steps 1-6 below) in full 2. **Search** the investigation JSON for IP enrichment data (`ip_enrichment` array) - **PRIMARY DATA SOURCE** 3. **Follow the documented steps** in order (SessionId → Authentication chain → Interactive MFA → Risk assessment) 4. **Use IP enrichment context** in your final risk assessment (VPN status, abuse scores, threat intel, auth patterns) **Skipping these steps will result in incomplete or incorrect analysis.** --- ## Key Forensic Indicators When investigating anomalous sign-ins (e.g., from new countries, IPs, or devices), it's critical to determine whether the user **actively performed MFA** at that location or if the authentication used a **refresh token from a prior session**. ### RequestSequence Field | Value | Meaning | Implication | |-------|---------|-------------| | `RequestSequence: 1` or higher | **Interactive authentication** | User was challenged and responded | | `RequestSequence: 0` | **Token-based authentication** | No user interaction required | ### AuthenticationDetails Array Patterns **Interactive Pattern:** - Array contains authentication method (e.g., "Passkey (device-bound)") with `RequestSequence > 0` - Followed by "Previously satisfied" entry **Token Reuse Pattern:** - Array contains ONLY "Previously satisfied" entries - Shows "MFA requirement satisfied by claim in the token" ### authenticationStepDateTime Correlation - If `authenticationStepDateTime` references a time when NO interactive auth occurred, it indicates token reuse - Cross-reference timestamps with events that have `RequestSequence > 0` to trace token origin --- ## IP Enrichment Data Structure (PRIMARY EVIDENCE SOURCE) **CRITICAL: The investigation JSON contains a comprehensive `ip_enrichment` array with authoritative detection flags.** **Always reference this data FIRST before making VPN/proxy/Tor determinations.** ### Example IP Enrichment Entry (Actual JSON Structure) ```json { "ip": "203.0.113.42", // ← KEY: Use "ip" field, not "ip_address" "city": "Singapore", "region": "Singapore", "country": "SG", "org": "AS12345 Example Hosting Ltd", "asn": "AS12345", "timezone": "Asia/Singapore", "risk_level": "HIGH", // ← Overall risk assessment (LOW/MEDIUM/HIGH) "assessment": "⚠️ Threat Intelligence Match: Commercial VPN Service Detected", "is_vpn": true, // ← PRIMARY VPN DETECTION FLAG (ipinfo.io detection) "is_proxy": false, // ← PRIMARY PROXY DETECTION FLAG "is_tor": false, // ← PRIMARY TOR DETECTION FLAG "abuse_confidence_score": 0, // ← AbuseIPDB score 0-100 (0=clean, 75+=high risk) "total_reports": 2, // ← Number of abuse reports in AbuseIPDB "is_whitelisted": false, "threat_description": "Commercial VPN Service: Known Anonymization Infrastructure", "anomaly_type": "NewInteractiveIP", "first_seen": "2025-10-16", // ← First sign-in from this IP (date string) "last_seen": "2025-10-16", // ← Last sign-in from this IP (date string) "hit_count": 5, // ← Number of anomaly detections "signin_count": 8, // ← Total sign-ins from this IP "success_count": 7, // ← Successful authentications "failure_count": 1, // ← Failed authentications "last_auth_result_detail": "MFA requirement satisfied by claim in the token", "threat_detected": false, // ← Legacy field (use threat_description instead) "threat_confidence": 0, "threat_tlp_level": "", "threat_activity_groups": "" } ``` **CRITICAL: Always use `ip_enrichment[].ip` to match IPs, NOT `ip_address`!** ### Key Fields for Analysis | Field | Purpose | Usage Example | |-------|---------|---------------| | **is_vpn** | Definitive VPN detection | `is_vpn: true` → Confirmed VPN endpoint (don't infer, use this flag) | | **is_proxy** | Definitive proxy detection | `is_proxy: true` → Confirmed proxy (anonymized traffic) | | **is_tor** | Definitive Tor detection | `is_tor: true` → Confirmed Tor exit node (high anonymity risk) | | **abuse_confidence_score** | AbuseIPDB reputation (0-100) | `>= 75` = High risk, `>= 25` = Medium risk, `0` = Clean | | **threat_detected** | Threat intel match flag | `true` → IP matches ThreatIntelIndicators table | | **threat_description** | Threat intel details | "Surfshark VPN", "Malicious activity detected", etc. | | **org / asn** | Network ownership | AS9009 = M247 Europe (VPN infrastructure provider) | | **signin_count** | Total sign-ins from IP | High count (>100) = established pattern vs transient | | **last_auth_result_detail** | Authentication method | "MFA satisfied by token" vs "Correct password" = interactive vs token reuse | | **first_seen / last_seen** | Temporal pattern | Single day = transient, multi-day = established behavior | ### Analysis Priority Hierarchy 1. **IP enrichment flags** (`is_vpn`, `is_proxy`, `is_tor`) - Most authoritative source 2. **Abuse reputation** (`abuse_confidence_score`, `total_reports`) - Community-validated risk data 3. **Threat intelligence** (`threat_detected`, `threat_description`) - IOC matches from Sentinel 4. **Network ownership** (`org`, `asn`, `company_type`) - Infrastructure context (hosting, ISP, etc.) 5. **Authentication patterns** (`last_auth_result_detail`, `signin_count`) - Behavioral context 6. **Identity Protection** (risk detections) - Microsoft ML-based risk signals **⚠️ NEVER say "likely VPN" or "probably proxy" if enrichment data has explicit boolean flags!** --- ## Forensic Workflow: Tracing Authentication Chains **Scenario:** Anomalous sign-ins detected from new IP/location. Determine if user performed fresh MFA or reused token. ### Tool Selection: AH-First, Data Lake Fallback | Lookback | Tool | Table | Why | |----------|------|-------|-----| | **≤ 30 days** (default) | `RunAdvancedHuntingQuery` | `EntraIdSignInEvents` | Single table covers interactive + non-interactive. No union needed. Direct columns for Country, City, Browser, UserAgent. Free on Analytics tier. | | **> 30 days** | `mcp_sentinel-data_query_lake` | `union SigninLogs, AADNonInteractiveUserSignInLogs` | AH Graph API caps at 30d. Data Lake retains 90d+. See [Data Lake Fallback Queries](#data-lake-fallback-queries--30d) below. | **Column mapping — `EntraIdSignInEvents` vs `SigninLogs`:** | EntraIdSignInEvents (AH) | SigninLogs (Data Lake) | Notes | |--------------------------|----------------------|-------| | `Timestamp` | `TimeGenerated` | | | `AccountUpn` | `UserPrincipalName` | | | `Application` | `AppDisplayName` | | | `ErrorCode` (int) | `ResultType` (string) | AH: `ErrorCode == 0`, DL: `ResultType == "0"` | | `Country`, `City` (direct strings) | `Location` or `parse_json(LocationDetails)` | No parsing needed in AH | | `LogonType` (JSON array) | Separate tables (SigninLogs vs AADNonInteractive) | AH: `has "interactiveUser"`, DL: check which table | | `AuthenticationRequirement` | `AuthenticationRequirement` | Same values: `singleFactorAuthentication`, `multiFactorAuthentication` | | `UserAgent`, `Browser`, `OSPlatform` | `parse_json(DeviceDetail)` | Direct columns in AH | | `UniqueTokenId` | *(not available)* | AH-only — token-level forensics | | `SessionId` | `SessionId` | Same | | *(not available)* | `AuthenticationDetails` (JSON array) | DL-only — per-step `RequestSequence` + `authenticationMethod` | > **Key trade-off:** `AuthenticationDetails` (Data Lake only) provides per-step `RequestSequence` and `authenticationMethod` ("Password", "Previously satisfied", "Mobile app notification"). `EntraIdSignInEvents` replaces this with row-level `LogonType` (interactive vs non-interactive) + `AuthenticationRequirement` (singleFactor/multiFactor) + `UniqueTokenId`. Both achieve the same forensic goal — determining interactive MFA vs token reuse — through different signals. **⚠️ Table name casing:** Capital `I` in `SignIn` — `EntraIdSignInEvents`, NOT `EntraIdSigninEvents`. **⚠️ `LogonType` is a JSON array string** (e.g., `["interactiveUser"]`). Use `has` for filtering, NOT `==`. **CRITICAL: START WITH SessionId - This is Your Primary and Most Efficient Investigation Pattern:** 1. **Query suspicious IP(s) to get SessionId** (single query for all suspicious IPs) 2. **Query SessionId for complete chain** — interactive vs non-interactive classification, geographic progression, token tracking 3. **Find interactive sign-ins** to determine where the user (or attacker) authenticated interactively - Expand date range progressively if needed: investigation window → 7 days → 30 days (AH limit) - **If > 30d lookback required:** Switch to Data Lake fallback queries (90d retention) **AVOID chronological searching without SessionId** - it requires multiple queries and is less efficient. --- ### Step 1: Get SessionId from Suspicious Authentication (ALWAYS START HERE) **Tool:** `RunAdvancedHuntingQuery` **This single query gives you SessionId AND enough context to determine next steps:** ```kql let suspicious_ips = dynamic(["", ""]); // All suspicious IPs EntraIdSignInEvents | where Timestamp > ago(30d) | where AccountUpn =~ '' | where IPAddress in (suspicious_ips) | project Timestamp, IPAddress, Country, City, Application, SessionId, LogonType, AuthenticationRequirement, UserAgent, Browser, OSPlatform, ErrorCode, UniqueTokenId | order by Timestamp asc | take 50 ``` **What This Returns:** - **SessionId(s)** for suspicious authentications (your primary key for Step 2) - Device fingerprint (UserAgent) to check for device consistency - Application context - Initial timeline **Critical Decision Point:** - **All suspicious IPs share same SessionId?** → Session continuity detected → Investigate further (could be legitimate user OR stolen token) - **Different SessionIds across IPs?** → Different authentication flows → Investigate device and authentication patterns - **IMPORTANT**: SessionId alone does NOT determine legitimacy - must correlate with UserAgent, geography, and behavior patterns --- ### Step 2: Trace Complete Authentication Chain by SessionId (DEFINITIVE PROOF) **Tool:** `RunAdvancedHuntingQuery` **Once you have SessionId from Step 1, query ALL authentications in that session:** ```kql let target_session_id = ""; EntraIdSignInEvents | where Timestamp > ago(30d) | where AccountUpn =~ '' | where SessionId == target_session_id | project Timestamp, IPAddress, Country, City, Application, LogonType, AuthenticationRequirement, ErrorCode, UserAgent, Browser, OSPlatform, UniqueTokenId | order by Timestamp asc ``` **This Single Query Reveals:** - **Complete geographic progression** (all IPs/locations in chronological order) - **Where interactive authentication occurred** (`LogonType has "interactiveUser"` + `AuthenticationRequirement == "multiFactorAuthentication"`) - **Token reuse pattern** (`LogonType has "nonInteractiveUser"` — all subsequent events using cached tokens) - **Device consistency** (Browser + UserAgent + OSPlatform should match across session) - **Time gaps** between locations (assess physical possibility of travel) - **Token-level tracking** (`UniqueTokenId` — same token reused across IPs = session continuity) **Critical Evidence - What SessionId Indicates:** - SessionId is a browser session identifier that tracks authentication flows - **Same SessionId across IPs** = Session continuity (could be legitimate user OR stolen token replay) - **SessionId does NOT prove device identity** - stolen refresh tokens maintain session continuity - **Same SessionId + Same UserAgent + Geographic impossibility** = Possible token theft - **Token theft attacks maintain the original SessionId** - attacker inherits session from stolen token - **CRITICAL**: Same SessionId does NOT rule out credential/token theft **Analysis Pattern:** 1. Look at FIRST authentication in session (earliest Timestamp) 2. Check if `LogonType has "interactiveUser"` → User performed interactive authentication at that IP/location 3. Check `AuthenticationRequirement` → `multiFactorAuthentication` = MFA was required and satisfied; `singleFactorAuthentication` = password-only 4. Subsequent events with `LogonType has "nonInteractiveUser"` = token reuse (expected OAuth flow) 5. Verify device consistency (Browser + UserAgent should match across session; different = possible token theft) 6. Assess geographic progression (impossible travel = high risk; reasonable = needs user confirmation) 7. Track `UniqueTokenId` — same token ID across geographically distant IPs = session continuity (could be VPN OR stolen token) --- ### Step 3: Find Interactive Sign-Ins with Progressive Date Range Expansion **Tool:** `RunAdvancedHuntingQuery` (≤30d) or Data Lake fallback (>30d) **Use this when Step 2 shows only `nonInteractiveUser` logon types (no interactive auth in the session)** **Query Pattern:** ```kql EntraIdSignInEvents | where Timestamp > ago(30d) | where AccountUpn =~ '' | where LogonType has "interactiveUser" | where ErrorCode == 0 | summarize SignInCount = count(), Apps = make_set(Application, 5), Countries = make_set(Country, 3), AuthReqs = make_set(AuthenticationRequirement), TokenIds = dcount(UniqueTokenId), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by IPAddress, SessionId | order by LastSeen desc | take 20 ``` **What This Returns:** - All IPs where the user performed interactive sign-ins, grouped by session - `AuthenticationRequirement` per IP — reveals whether MFA was required or bypassed - `TokenIds` count — how many distinct tokens were issued from each IP/session pair - **Match SessionIds** against Step 1 results — if the suspicious SessionId also has interactive sign-ins from a VPS IP, the attacker has the password **Progressive expansion (if AH 30d window is insufficient):** - If no interactive sign-ins found in 30d → Switch to Data Lake fallback queries for 90d lookback - Tokens can be valid for up to 90 days depending on tenant policy --- ### Data Lake Fallback Queries (>30d) **Use these when the AH 30d window is insufficient — e.g., tracing token origins older than 30 days.** **Tool:** `mcp_sentinel-data_query_lake` with `workspaceId` **Step 1 (Data Lake):** ```kql let suspicious_ips = dynamic(["", ""]); union isfuzzy=true SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(90d) | where UserPrincipalName =~ '' | where IPAddress in (suspicious_ips) | project TimeGenerated, IPAddress, Location, AppDisplayName, SessionId = tostring(SessionId), UserAgent, ResultType, CorrelationId | order by TimeGenerated asc | take 50 ``` **Step 2 (Data Lake) — with per-step auth detail:** ```kql let target_session_id = ""; union isfuzzy=true SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(90d) | where UserPrincipalName =~ '' | where SessionId == target_session_id | extend AuthDetails = parse_json(tostring(AuthenticationDetails)) | mv-expand AuthDetails | extend AuthMethod = tostring(AuthDetails.authenticationMethod) | extend AuthStepDateTime = todatetime(AuthDetails.authenticationStepDateTime) | extend RequestSeq = toint(AuthDetails.RequestSequence) | project TimeGenerated, IPAddress, Location, AppDisplayName, AuthMethod, AuthStepDateTime, RequestSeq, UserAgent, ResultType | order by TimeGenerated asc ``` > **Data Lake advantage:** `AuthenticationDetails` provides granular per-step `RequestSequence` and `authenticationMethod` ("Password", "Previously satisfied", "Mobile app notification") not available in `EntraIdSignInEvents`. Use this for forensic-grade MFA step tracing when AH's `LogonType` + `AuthenticationRequirement` columns are insufficient. **Step 3 (Data Lake) — interactive MFA search:** ```kql union isfuzzy=true SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(90d) | where UserPrincipalName =~ '' | extend AuthDetails = parse_json(tostring(AuthenticationDetails)) | mv-expand AuthDetails | extend AuthMethod = tostring(AuthDetails.authenticationMethod) | extend RequestSeq = toint(AuthDetails.RequestSequence) | where AuthMethod != "Previously satisfied" | where RequestSeq > 0 | project TimeGenerated, IPAddress, Location, AppDisplayName, AuthMethod, RequestSeq, SessionId = tostring(SessionId), UserAgent, ResultType | order by TimeGenerated desc | take 30 ``` --- ### Step 4: Collect All IPs from Authentication Chain **CRITICAL: After completing the SessionId trace, extract ALL unique IP addresses discovered:** 1. **From Interactive MFA session** (Step 3 results) 2. **From Suspicious session** (Step 1 results) 3. **From Complete SessionId chain** (Step 2 results) **Build comprehensive IP list for enrichment analysis.** --- ### Step 5: Analyze IP Enrichment Data for ALL Discovered IPs **MANDATORY: Search investigation JSON `ip_enrichment` array for EVERY IP in the authentication chain:** For each IP address discovered in Steps 1-3: 1. **Locate IP in `ip_enrichment` array** (search by `"ip": ""` field) 2. **Extract key risk indicators:** - `is_vpn`, `is_proxy`, `is_tor` (anonymization detection) - `abuse_confidence_score`, `total_reports` (reputation) - `threat_description`, `threat_detected` (threat intel matches) - `org`, `asn` (network ownership - hosting vs ISP) - `last_auth_result_detail` (authentication pattern) - `signin_count`, `success_count`, `failure_count` (frequency/behavior) - `first_seen`, `last_seen` (temporal pattern - transient vs established) 3. **Document findings for EACH IP in the chain:** - Geographic location + ISP/VPN status - Risk level + threat intelligence status - Authentication pattern (interactive vs token reuse) - Behavioral context (frequency, success rate, temporal pattern) **This creates a complete evidence picture showing the full authentication journey with enrichment context.** --- ### Step 6: Document Risk Assessment **⚠️ MANDATORY CHECKPOINT - Before writing risk assessment:** - **READ** the "When to Escalate Authentication Anomalies" section below - **IDENTIFY** which risk classification criteria applies to your case - **QUOTE** the specific criteria in your analysis - **DO NOT improvise** - follow documented classification exactly **Present findings in clear evidence trail:** 1. **Interactive Session**: IP, Location, Timestamp, AuthMethod, SessionId 2. **Subsequent Session**: IP, Location, Timestamp, AuthMethod (token-based), SessionId 3. **IP Enrichment Analysis for ALL IPs**: Present enrichment data for EVERY IP discovered in trace (VPN status, abuse scores, threat intel, auth patterns, frequency, temporal context) 4. **Connection Proof**: SessionId match + time gap + geographic distance + comprehensive enrichment context from all IPs 5. **Risk Assessment**: Evaluate based on context - **MUST quote specific instruction criteria** **Risk Assessment Framework - SessionId Interpretation:** - **SessionId does NOT prove device identity** - token theft maintains session continuity - **Same SessionId across geographically distant IPs** = Requires investigation (VPN/travel OR stolen token) - **Different SessionIds** = Different authentication flows (not necessarily more suspicious) - **Must correlate multiple signals**: SessionId + UserAgent + Geography + Behavior + Time patterns + **IP enrichment data** --- ## Real-World Example: Geographic Anomaly Analysis **Scenario:** User sign-ins detected from two geographically distant locations within 18 hours. ### Step 1: Interactive MFA Analysis **Location A Analysis:** 1. Query 1: Found 2 events with `SMS verification` and `RequestSeq: 1` 2. Result: **User performed fresh interactive SMS authentication at Location A** 3. Evidence: `authenticationStepDateTime: 2025-10-15T14:23:05Z` with `RequestSequence: 1` **Location B Analysis:** 1. Query 1: Zero results (no non-"Previously satisfied" methods) 2. Result: **Location B authentications used only token reuse - NO interactive MFA** 3. Evidence: All events show `"MFA requirement satisfied by claim in the token"` ### Step 2: SessionId Verification (SMOKING GUN) **Query to compare sessions across both IPs:** ```kql let suspicious_ips = dynamic(["", ""]); union isfuzzy=true SigninLogs, AADNonInteractiveUserSignInLogs | where TimeGenerated between (datetime() .. datetime()) | where UserPrincipalName =~ '' | where IPAddress in (suspicious_ips) | project TimeGenerated, IPAddress, Location, SessionId, UserAgent | order by TimeGenerated asc ``` **CRITICAL FINDING:** - **SessionId: ``** - **ALL Location A authentications**: Same SessionId (over time period 1) - **ALL Location B authentications**: Same SessionId (over time period 2) - **Time gap**: Varies (analyze based on context) - **Geographic distance**: Varies (analyze based on context) **Initial Appearance:** Potential geographic anomaly requiring investigation **Further Analysis Required:** Correlate SessionId with UserAgent, behavior patterns, and user confirmation ### Step 3: Evidence Summary and Interpretation | Evidence Type | Finding | Observation | |--------------|---------|-------------| | Interactive MFA | Location A only | User performed SMS authentication | | Location B Auth Methods | "Previously satisfied" only | Token reuse (normal OAuth flow) | | SessionId | Same across both locations | **Session continuity maintained** | | Time Gap | 18 hours | Within typical refresh token lifetime (24-90 days) | | User Agent | Same | **Consistent device fingerprint** | | Applications | Consistent across locations | Consistent workflow pattern | ### Critical Analysis - SessionId Does NOT Prove Legitimacy The **same SessionId** requires careful analysis because: - SessionId is a browser session identifier that tracks authentication flows - **Same SessionId = Session continuity** (could be legitimate user OR stolen token) - **Stolen refresh tokens maintain the original SessionId** - attacker inherits session state - **Same SessionId does NOT rule out token theft or credential compromise** **Possible Scenarios Requiring Investigation:** | Scenario | Description | Action Required | |----------|-------------|-----------------| | **Legitimate VPN Connection** | User switched VPN exit nodes (same device, different apparent location) | **Requires user confirmation** | | **Legitimate User Travel** | User traveled between locations with sufficient time gap (tokens remained valid) | **Requires user confirmation** | | **Multi-Device User** | User has laptop + phone active simultaneously (different IPs, concurrent activity) | **Check UserAgent for mobile vs desktop - Requires user confirmation** | | **Stolen Token Replay** | Attacker obtained refresh token (SessionId stays same, may show different UserAgent) | **Cannot be ruled out by SessionId alone** | | **Mobile Carrier Routing** | Carrier routes traffic through regional gateways (device in one location, exits another) | **Check IP enrichment for ISP org** | ### Additional Investigation Checklist - ✅ Check UserAgent consistency across all sessions - ✅ **Distinguish mobile vs desktop UserAgents** - Concurrent activity from different device types (e.g., Android Chrome + Windows Edge) may indicate legitimate multi-device usage, not token theft - ✅ Verify geographic progression is physically possible - ✅ Review applications accessed (any unusual admin tools?) - ✅ Check for failed authentication attempts before success - ✅ Look for account modifications or privilege changes - ✅ **Check IP enrichment data in investigation JSON** - Use `ip_enrichment` array to verify: - VPN/proxy/Tor status (`is_vpn`, `is_proxy`, `is_tor`) - Abuse reputation (`abuse_confidence_score`, `total_reports`) - Threat intelligence matches (`threat_detected`, `threat_description`) - Authentication patterns (`last_auth_result_detail`, `signin_count`, `success_count`, `failure_count`) - Temporal context (`first_seen`, `last_seen` - transient vs established pattern) - ✅ **Most important: Confirm with user directly** ### Recommendation: User Confirmation Questions **Use IP enrichment data from investigation JSON to strengthen your analysis, then confirm with user:** 1. "Were you using a VPN on [date] around [time]?" (if `is_vpn: true`) 2. "Did you travel between [Location A] and [Location B] during this timeframe?" 3. "Were you using multiple devices (e.g., laptop and phone) at the same time?" (if concurrent activity with different UserAgents detected) 4. "Do you recognize [applications] activity during this timeframe?" 5. "Have you noticed any unusual device or account behavior recently?" **Only after user confirmation** can you conclude VPN usage or travel is legitimate. **Same SessionId + IP enrichment data together provide strong evidence, but user confirmation is still required.** --- ## Common Authentication Methods and RequestSequence Patterns | Authentication Method | RequestSeq > 0 Meaning | RequestSeq = 0 Meaning | |----------------------|------------------------|------------------------| | Passkey (device-bound) | User physically approved with biometric/PIN | Passkey used in prior session, token reused | | Phone sign-in | User approved notification on phone | Phone approval in prior session, token reused | | SMS verification | User entered SMS code | SMS verification in prior session, token reused | | Microsoft Authenticator app | User approved push notification | Authenticator used in prior session, token reused | | Previously satisfied | N/A - never has RequestSeq > 0 | Always indicates token/claim reuse | --- ## When to Escalate Authentication Anomalies **CRITICAL: Always check IP enrichment data before making risk determination!** ### High Risk (Escalate Immediately) - Token reuse from geographically impossible locations (regardless of SessionId) - Token reuse after user reports device loss/theft - Concurrent sessions from multiple countries simultaneously **with same UserAgent** (same device can't be in two places) - **Note:** Concurrent activity with **different UserAgents** (mobile vs desktop) may indicate legitimate multi-device usage - verify before escalating - Token reuse from IPs matching ThreatIntelIndicators OR `threat_detected: true` in IP enrichment - Unusual application access (admin portals, sensitive resources not in user's normal pattern) - Failed authentication attempts followed by successful token reuse - Account modifications or privilege escalations during suspicious sessions - **Geographic anomaly + Same SessionId + Different UserAgent** = Likely token theft - **Impossible travel time between authentications** (regardless of SessionId) - **IP enrichment shows**: `abuse_confidence_score >= 75`, `is_tor: true`, or malicious `threat_description` ### Medium Risk (Investigate Further - Confirm with User) - **Same SessionId + Geographically distant locations** = Could be VPN/travel OR token theft - VERIFY with IP enrichment - **Concurrent activity from different IPs with different UserAgents** = Could be multi-device (laptop + phone) OR token theft - ASK user about device usage - Token reuse from unexpected country without prior user notification - Token reuse spanning >30 days (excessive token lifetime - increases theft window) - Pattern of token-only authentications without any interactive MFA in 30+ days - Sign-ins during unusual hours for user's timezone - Access to sensitive data repositories during suspicious sessions - **Same SessionId + Same UserAgent + Unusual geographic pattern** = Needs user confirmation - **IP enrichment shows**: `abuse_confidence_score >= 25`, `is_vpn: true` without user confirmation, or `total_reports > 0` ### Low Risk / Likely Legitimate (Monitor Only) - Token reuse from nearby IPs in same city (mobile carrier IP rotation) - Token reuse following confirmed interactive MFA from expected location - Token reuse from known corporate VPN IP ranges - Applications and access patterns consistent with user's role - **User confirms VPN usage or travel** when questioned - No unusual data access or configuration changes - **Consistent UserAgent + Reasonable geographic progression + User confirmation** - **IP enrichment shows**: `abuse_confidence_score: 0`, residential ISP org (TELUS, Comcast, etc.), `is_vpn: false`, high `signin_count` with consistent success rate --- ## Best Practices for Authentication Tracing 1. **START WITH SessionId** - Query suspicious IPs to get SessionId first (most efficient approach) 2. **Use SessionId to trace complete chain** - Single query shows entire authentication progression 3. **Check IP enrichment data** - Use investigation JSON `ip_enrichment` array for VPN, abuse scores, threat intel 4. **Verify device consistency** - Same SessionId + Same UserAgent + Geographic reasonableness = Likely legitimate 5. **Check for multi-device scenarios** - Different UserAgents (mobile vs desktop) with concurrent activity often indicates legitimate multi-device usage, not token theft. Users commonly work on laptop while checking email on phone. 6. **Concurrent activity ≠ Automatic compromise** - Before concluding token theft from concurrent sessions, verify UserAgent differences and ask user about device usage patterns 7. **SessionId alone is NOT conclusive** - Must correlate with UserAgent, geography, behavior, and user confirmation 6. **Check first authentication in session** - RequestSeq > 0 shows where user performed interactive MFA 7. **Assess geographic progression** - Evaluate if travel is physically possible or if VPN is likely 8. **Widen time ranges if needed** - Tokens can be valid for 24-90 days depending on policy 9. **Always confirm with user** - Geographic anomalies require user verification regardless of SessionId --- ## Prerequisites ### Required MCP Servers This skill requires: 1. **Sentinel Triage MCP** (primary, ≤30d) — `RunAdvancedHuntingQuery` for `EntraIdSignInEvents` 2. **Microsoft Sentinel Data Lake MCP** (fallback, >30d) — `mcp_sentinel-data_query_lake` for `SigninLogs` + `AADNonInteractiveUserSignInLogs` union ### Required Data Sources - **EntraIdSignInEvents** (primary) — Unified interactive + non-interactive sign-in events. Advanced Hunting only, 30d retention via Graph API - **SigninLogs** + **AADNonInteractiveUserSignInLogs** (fallback) — Sentinel Data Lake, 90d+ retention. Required when tracing token origins older than 30 days or when `AuthenticationDetails` per-step granularity is needed - **Investigation JSON** - Pre-generated investigation file with `ip_enrichment` array (from user-investigation skill) ### How to Find Investigation JSON - **Pattern**: `temp/investigation__.json` - Most recent file for user is usually the one to analyze - Use `file_search` or `list_dir` to locate existing investigations --- ## Integration with User Investigation Skill Authentication tracing is typically performed as a **follow-up analysis** after running a user investigation: 1. **Run user-investigation skill** → Generates investigation JSON with `ip_enrichment` array 2. **Review anomalies** → Identify suspicious IPs/locations requiring deeper analysis 3. **Run authentication-tracing skill** → Trace SessionId chains, correlate with IP enrichment 4. **Document findings** → Provide risk assessment with evidence trail **Key Integration Points:** - IP enrichment data comes from investigation JSON (already queried by user-investigation) - SessionId queries are NEW queries specific to authentication tracing - Risk assessment combines both data sources