← Back to SOC feed Coverage →

Invited Guest User but not redeemed Invite for longer period.

kql MEDIUM Azure-Sentinel
T1078.004
AuditLogs
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-04-23T09:00:00Z · Confidence: medium

Hunt Hypothesis

Guest users who have been invited but have not redeemed their invite within an unusually long period may indicate potential misuse or reconnaissance by an adversary seeking to exploit long-term access. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate potential lateral movement or persistence tactics.

KQL Query

let lookback = 14d;
let invitethreshold = 5d;
// Collect external user invitations
let ExtUserInvites = AuditLogs
| where TimeGenerated > ago(lookback)
| where Category =~ "UserManagement"
| where OperationName =~ "Invite external user"
| extend TargetUPN = tostring(TargetResources[0].["userPrincipalName"])
| extend InviteInitiator = tostring(InitiatedBy.["user"].["userPrincipalName"]) , IPAddress = tostring(InitiatedBy.["user"].["ipAddress"])
| where isnotempty(InviteInitiator)
| extend InviteTime = TimeGenerated;
// Collect redeem events
let ExtUserRedeem = AuditLogs
| where TimeGenerated > ago(lookback)
| where Category =~ "UserManagement"
| where OperationName =~ "Redeem external user invite"
| where Result =~ "success"
| extend InviteInitiator = tostring(InitiatedBy.["user"].["userPrincipalName"])
| extend Target = tostring(TargetResources[0].["userPrincipalName"])
| extend TargetUPN = tostring(extract(@"UPN\:\s(.+)\,\sEmail",1,Target))
| where isnotempty(Target);
// Find invites who have not been redeemed since long time.
ExtUserInvites
| join kind=leftanti ( ExtUserRedeem ) on TargetUPN
| where InviteTime > ago(invitethreshold)
| project TimeGenerated

Analytic Rule Definition

id: 1ad620f0-fee4-4bb7-a2b3-62af7f18332b
name: Invited Guest User but not redeemed Invite for longer period.
description: |
  'This query will look for events where guest user was invited but has not accepted/redeemed invite for unusually longer period. 
   Any invites not redeemed for longer period of time can be misused and pose risk if suspiciously redeemed in other ways'
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AuditLogs
tactics:
  - InitialAccess
relevantTechniques:
  - T1078.004
tags:
  - GuestorExternalIdentities
query: |
  let lookback = 14d;
  let invitethreshold = 5d;
  // Collect external user invitations
  let ExtUserInvites = AuditLogs
  | where TimeGenerated > ago(lookback)
  | where Category =~ "UserManagement"
  | where OperationName =~ "Invite external user"
  | extend TargetUPN = tostring(TargetResources[0].["userPrincipalName"])
  | extend InviteInitiator = tostring(InitiatedBy.["user"].["userPrincipalName"]) , IPAddress = tostring(InitiatedBy.["user"].["ipAddress"])
  | where isnotempty(InviteInitiator)
  | extend InviteTime = TimeGenerated;
  // Collect redeem events
  let ExtUserRedeem = AuditLogs
  | where TimeGenerated > ago(lookback)
  | where Category =~ "UserManagement"
  | where OperationName =~ "Redeem external user invite"
  | where Result =~ "success"
  | extend InviteInitiator = tostring(InitiatedBy.["user"].["userPrincipalName"])
  | extend Target = tostring(TargetResources[0].["userPrincipalName"])
  | extend TargetUPN = tostring(extract(@"UPN\:\s(.+)\,\sEmail",1,Target))
  | where isnotempty(Target);
  // Find invites who have not been redeemed since long time.
  ExtUserInvites
  | join kind=leftanti ( ExtUserRedeem ) on TargetUPN
  | where InviteTime > ago(invitethreshold)
  | project TimeGenerated
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: InviteInitiator
  - entityType: IP
    fieldMappings:
      - identifier: Address
        columnName: IPAddress
version: 1.0.0 

Required Data Sources

Sentinel TableNotes
AuditLogsEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/AuditLogs/NonredeemedGuesUserInvites.yaml