← Back to SOC feed Coverage →

Approved Access Packages Details

kql MEDIUM Azure-Sentinel
T1556
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-22T09:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may exploit approved access packages to maintain persistent access within an organization by leveraging legitimate administrative privileges. SOC teams should proactively hunt for unusual approval patterns or access justifications in Azure Sentinel to identify potential abuse of governance tools.

KQL Query

//Approved requests for all Access Packages with timestamps and justifications
AuditLogs
| where OperationName == "User requests access package assignment"
| mv-apply AdditionalDetails on ( 
  where AdditionalDetails.key == "Justification"
  | extend RequestorJustification = tostring(AdditionalDetails.value)
  )
| mv-apply TR=TargetResources on (
  where TR.type == "AccessPackageAssignmentRequest"
  | extend RequestID = tostring(TR.id)
  )
| mv-apply TR=TargetResources on (
  where TR.type == "AccessPackage"
  | extend AccessPackageName = tostring(TR.displayName)
  )
| extend RequestedBy = tostring(InitiatedBy.user.userPrincipalName)
| distinct TimeRequested = TimeGenerated, AccessPackageName, RequestedBy, RequestorJustification, CorrelationId, RequestID
| join kind=inner (
  AuditLogs 
  | where OperationName == "Approve access package assignment request"
  | extend ApprovedBy = InitiatedBy.user.userPrincipalName
  | project ApprovedTime = TimeGenerated, ApprovedBy, CorrelationId
  ) on CorrelationId
| join kind=leftouter (
  AuditLogs
  | where OperationName == "Request approved"
  | mv-apply AdditionalDetails on ( 
      where AdditionalDetails.key == "Justification"
      | extend ApproverJustification = tostring(AdditionalDetails.value)
      )
  | mv-apply TargetResources on (
      where TargetResources.type == "Other"
      | extend RequestID = tostring(TargetResources.id)
  )
  | project ApproverJustification, RequestID
  ) on RequestID
| project TimeRequested, AccessPackageName, RequestedBy, RequestorJustification, ApprovedTime, ApprovedBy, ApproverJustification, CorrelationId, RequestID
| order by TimeRequested asc

Analytic Rule Definition

id: aff7eb5f-3359-48ab-b73b-6c466d3806dc
name: Approved Access Packages Details
description: |
  This query shows details about all approved Entra ID Governance Access Packages assignments. The results include the time the request was created and approved along with the justification text provided by the requestor and the approver.
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AuditLogs
tactics:
  - DefenseEvasion
  - Persistence
relevantTechniques:
  - T1556
query: |
  //Approved requests for all Access Packages with timestamps and justifications
  AuditLogs
  | where OperationName == "User requests access package assignment"
  | mv-apply AdditionalDetails on ( 
    where AdditionalDetails.key == "Justification"
    | extend RequestorJustification = tostring(AdditionalDetails.value)
    )
  | mv-apply TR=TargetResources on (
    where TR.type == "AccessPackageAssignmentRequest"
    | extend RequestID = tostring(TR.id)
    )
  | mv-apply TR=TargetResources on (
    where TR.type == "AccessPackage"
    | extend AccessPackageName = tostring(TR.displayName)
    )
  | extend RequestedBy = tostring(InitiatedBy.user.userPrincipalName)
  | distinct TimeRequested = TimeGenerated, AccessPackageName, RequestedBy, RequestorJustification, CorrelationId, RequestID
  | join kind=inner (
    AuditLogs 
    | where OperationName == "Approve access package assignment request"
    | extend ApprovedBy = InitiatedBy.user.userPrincipalName
    | project ApprovedTime = TimeGenerated, ApprovedBy, CorrelationId
    ) on CorrelationId
  | join kind=leftouter (
    AuditLogs
    | where OperationName == "Request approved"
    | mv-apply AdditionalDetails on ( 
        where AdditionalDetails.key == "Justification"
        | extend ApproverJustification = tostring(AdditionalDetails.value)
        )
    | mv-apply TargetResources on (
        where TargetResources.type == "Other"
        | extend RequestID = tostring(TargetResources.id)
    )
    | project ApproverJustification, RequestID
    ) on RequestID
  | project TimeRequested, AccessPackageName, RequestedBy, RequestorJustification, ApprovedTime, ApprovedBy, ApproverJustification, CorrelationId, RequestID
  | order by TimeRequested asc
entityMappings:
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: RequestedBy
  - entityType: Account
    fieldMappings:
      - identifier: FullName
        columnName: ApprovedBy

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/ApprovedAccessPackagesDetails.yaml