Agent Foskett Case File • Microsoft Entra ID • Enterprise Applications • App Roles • Microsoft Graph • AuditLogs • KQL

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?

Agent Foskett investigating unexpected Microsoft Entra enterprise application permissions
The Application Was Familiar. The Permission Wasn't.

Current state shows what exists now. Audit evidence helps explain how it got there.

✓ Identify the service principal
✓ Reconstruct the app role assignment
✓ Follow the workload activity

The application object was not the whole story

Microsoft Entra separates an application registration from the service principal that represents the application inside a tenant.

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

Agent Foskett preserved both the enterprise application's service principal object ID and its application/client ID.

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?

The current configuration showed powerful application permissions to Microsoft Graph.

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

Where Microsoft Entra audit logs were exported to Log Analytics, Agent Foskett searched for app-role assignment activity and preserved the complete initiator and target context.
app-role-assignment-events.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 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 desc

The exact operation name mattered

Agent Foskett first discovered the relevant 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.
app-role-targets.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 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 desc

A GUID was not a permission name

An app-role assignment connects a client service principal to an app role exposed by a resource service principal such as Microsoft Graph.

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.
permission-grant-initiator.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 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,
          CorrelationId

Attribution was not authorization

Finding the administrator who performed the operation did not automatically make the grant legitimate.

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?

Agent Foskett widened the timeline around the service principal. Credential additions, service-principal updates or other permission changes near the grant could materially change the investigation.
service-principal-change-timeline.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 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 asc

Could the application actually use the permission?

An app-role assignment establishes authorization. It does not prove the application subsequently authenticated and exercised 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

Where service-principal sign-in logs were exported to Log Analytics, Agent Foskett examined AADServicePrincipalSignInLogs for the client service principal.
enterprise-app-signins.kql
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 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 asc

A Graph sign-in still did not prove the API operation

A successful workload sign-in to Microsoft Graph can establish authentication against that resource. It does not by itself identify which Graph API operation followed.

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

Application already existsPreserve the application ID and tenant-local service principal object ID.
Unexpected permission discoveredDocument the current app-role assignment and resolve the role ID.
Grant event identifiedUse AuditLogs to locate the relevant application-management operation.
Initiator establishedDetermine which user or application initiated the change.
Surrounding changes reviewedLook for credentials and other service-principal changes.
Usage scopedCheck workload authentication and downstream evidence of actual use.

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

The enterprise application looked familiar.

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.
Investigation principle: When an enterprise application has unexpected access, separate what it can do now, how it gained that access and whether the permission was actually exercised.
The application was familiar. The permission wasn't.
Identify the service principal. Reconstruct the grant. Follow the workload activity.
Continue the Investigation

Final thought

Enterprise applications can quietly accumulate powerful access.

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! 🔎
Develop IT.. Protect IT.. GEMXIT.
GEMXIT PTY LTD | GEMXIT UK LTD
Talk to GEMXIT

The Enterprise Application Had Access — Nobody Remembered Granting It

This Agent Foskett investigation examines unexpected Microsoft Entra enterprise application permissions using service principals, app role assignments, AuditLogs and KQL.

Investigating Microsoft Entra Enterprise Application Permissions

Identify the tenant service principal, resolve application permissions exposed by Microsoft Graph or another API and reconstruct app-role assignment activity from Microsoft Entra audit evidence.

Who Granted the Application Permission?

Use AuditLogs to investigate the initiator, surrounding application-management changes and subsequent service-principal authentication while separating current privilege, change history and actual permission use.