The Enterprise Application Had Access — Nobody Remembered Granting It
The enterprise application was not new.
Its name looked familiar.
Its service principal had existed for months.
But its effective access was more powerful than anyone expected.
Microsoft Graph application permissions were assigned to it — and nobody remembered approving them.
What permissions did it actually hold?
When were they assigned?
And who granted them?

The Application Was Familiar. The Permission Wasn't.
Current state shows what exists now. Audit evidence helps explain how it got there.
The application object was not the whole story
The enterprise application view is centred on that service principal.
Agent Foskett did not stop after checking when the application was created. The permission could have changed without the application itself being recreated.
Start with the service principal
The object ID identifies the tenant-local service principal. The application ID identifies the application.
The investigation followed the tenant principal that actually held the access.
What access was actually assigned?
Application permissions are app roles assigned to the client service principal. They are different from delegated permissions exercised on behalf of a signed-in user.
Before asking who granted access, establish exactly what access exists.
Find app-role assignment events in AuditLogs
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
AuditLogs
| where TimeGenerated > ago(90d)
| where Category =~ "ApplicationManagement"
| where OperationName has "app role assignment"
| project TimeGenerated,
OperationName,
Result,
InitiatedBy,
TargetResources,
AdditionalDetails,
CorrelationId
| order by TimeGenerated descThe exact operation name mattered
ApplicationManagement operations in the tenant's available telemetry, then narrowed the investigation to the app-role assignment events returned there.Use the evidence to discover the event vocabulary before hard-coding the investigation around a label.
Which service principal received the role?
TargetResources contains objects affected by an Entra audit operation. Agent Foskett expanded the array rather than assuming the first target told the whole story.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
AuditLogs
| where TimeGenerated > ago(90d)
| where Category =~ "ApplicationManagement"
| where OperationName has "app role assignment"
| mv-expand Target = TargetResources
| extend TargetName = tostring(Target.displayName),
TargetId = tostring(Target.id),
TargetType = tostring(Target.type)
| project TimeGenerated,
OperationName,
TargetName,
TargetId,
TargetType,
InitiatedBy,
CorrelationId
| order by TimeGenerated descA GUID was not a permission name
Agent Foskett resolved the app role ID against the resource service principal's published roles before describing the effective permission.
Client principal, resource principal and app role are three different parts of the relationship.
Who initiated the permission change?
InitiatedBy was the next pivot. Depending on the workflow, the audit record can contain user or application context for the identity that initiated the directory operation.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
AuditLogs
| where TimeGenerated > ago(90d)
| where Category =~ "ApplicationManagement"
| where OperationName has "app role assignment"
| extend InitiatingUser =
tostring(InitiatedBy.user.userPrincipalName),
InitiatingUserId =
tostring(InitiatedBy.user.id),
InitiatingApp =
tostring(InitiatedBy.app.displayName),
InitiatingAppId =
tostring(InitiatedBy.app.servicePrincipalId)
| project TimeGenerated,
OperationName,
InitiatingUser,
InitiatingUserId,
InitiatingApp,
InitiatingAppId,
TargetResources,
CorrelationIdAttribution was not authorization
Agent Foskett checked whether the permission matched the application's documented purpose, whether an approved change existed and whether the administrator expected to grant that exact access.
Attribution answers who performed the operation. Authorization answers whether they were supposed to.
What else changed around the grant?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
let ServicePrincipalObjectId =
"11111111-2222-3333-4444-555555555555";
AuditLogs
| where TimeGenerated > ago(90d)
| where Category =~ "ApplicationManagement"
| where tostring(TargetResources)
has ServicePrincipalObjectId
| project TimeGenerated,
OperationName,
Result,
InitiatedBy,
TargetResources,
CorrelationId
| order by TimeGenerated ascCould the application actually use the permission?
Agent Foskett separated three questions:
Was the permission assigned?
Could the workload authenticate?
Did downstream telemetry show the access being used?
Check workload sign-in activity
AADServicePrincipalSignInLogs for the client service principal.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
let ServicePrincipalObjectId =
"11111111-2222-3333-4444-555555555555";
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(30d)
| where ServicePrincipalId
=~ ServicePrincipalObjectId
| project TimeGenerated,
ServicePrincipalName,
AppId,
IPAddress,
ResourceDisplayName,
ResultType,
ResultDescription,
CorrelationId
| order by TimeGenerated ascA Graph sign-in still did not prove the API operation
To prove actual data access or administrative action, Agent Foskett needed downstream service or audit telemetry.
Token acquisition is not the same thing as proving how the token was used.
Build the enterprise-application permission timeline
What the evidence can and cannot prove
AuditLogs can establish Entra directory operations when the required telemetry is available and retained. Current service-principal configuration can establish which app-role assignments exist now. AADServicePrincipalSignInLogs can establish observed workload authentication where those logs are collected.A current permission does not tell you when it was granted. A grant event does not prove it was used. A workload sign-in does not identify every downstream API operation.
Current state, change history and actual usage are three different evidence questions.
The lesson
That familiarity nearly ended the investigation too early.
Agent Foskett followed the service principal, identified the effective app role, reconstructed the permission assignment, established the initiator and checked what changed around it.
Application permissions are privileges. Their history belongs on the incident timeline.
Related investigations
Final thought
When the access looks wrong, start with the current assignment and work backwards.
Resolve the permission. Find the grant event. Identify the initiator. Then determine whether the workload actually used what it had been given.
The application hadn't suddenly appeared.
The privilege had.
Follow the evidence. Build the timeline.
The Logs Already Knew! 🔎

