Agent Foskett Investigation • Microsoft Entra ID • Conditional Access • AuditLogs • SigninLogs • KQL

The Admin Changed One Conditional Access Policy — 43 Accounts Became Exposed

Nothing crashed.

No one lost access.
No alert screamed that something had gone wrong.

An administrator had made what looked like a routine Conditional Access change.

Then Agent Foskett compared the policy history with the sign-in evidence.

One scope change had quietly reduced protection for dozens of identities.

One policy changed. Forty-three accounts were now outside the protection everyone thought they still had.

Agent Foskett investigating a Microsoft Entra Conditional Access policy change
The Policy Still Existed

The problem was not that Conditional Access had disappeared. The policy was still there. The investigation had to determine what changed, who changed it and which sign-ins were no longer protected as expected.

✓ Reconstruct the policy change
✓ Compare old and new scope
✓ Measure affected sign-ins and accounts

The dangerous change looked routine

Conditional Access is policy logic. A small change to users, groups, applications, conditions, exclusions or grant controls can materially alter who receives protection. Microsoft Entra records policy updates in the audit log, which makes the policy history the first place to investigate.
Policy still presentThe security control had not been deleted.
Scope had changedThe protection no longer applied to the same set of identities.
Impact appeared in sign-insThe sign-in telemetry showed where the policy was no longer applied as expected.

Find the Conditional Access policy update

Microsoft Entra audit logs record Conditional Access policy changes. In Log Analytics, AuditLogs can be filtered for Update Conditional Access policy to identify when the change occurred and who initiated it.
conditional-access-policy-changes.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
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName == "Update Conditional Access policy"
| project TimeGenerated,
          OperationName,
          Result,
          InitiatedBy,
          TargetResources,
          AdditionalDetails
| order by TimeGenerated desc

Preserve the modified properties

The important evidence is not merely that the policy was updated. The target resource can contain the modified properties that describe the old and new policy values. Those values are often represented as JSON, so the investigation should preserve them for side-by-side comparison rather than reducing the event to a single “policy changed” line.
extract-policy-modified-properties.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
AuditLogs
| where TimeGenerated > ago(30d)
| where OperationName == "Update Conditional Access policy"
| mv-expand Target = TargetResources
| extend PolicyName = tostring(Target.displayName),
         ModifiedProperties = Target.modifiedProperties
| project TimeGenerated,
          PolicyName,
          InitiatedBy,
          ModifiedProperties
| order by TimeGenerated desc

What changed?

A Conditional Access policy can change in many ways: included users, excluded users or groups, cloud applications, client app types, locations, device conditions, session controls or grant controls. The investigation should identify the exact old and new value before describing the security impact.
User or group scopeAn exclusion or scope reduction can quietly remove identities from protection.
Application scopeA policy can remain enabled while no longer protecting the same resources.
Grant controlsChanging MFA, compliant-device or block requirements can materially alter enforcement.

Move from the policy change to real sign-ins

SigninLogs exposes the overall Conditional Access status and the individual policies evaluated for a sign-in. Start at the policy-change timestamp and inspect the sign-ins that followed.
signins-after-policy-change.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
let ChangeTime = datetime(2026-08-27 02:15:00);
SigninLogs
| where TimeGenerated between (ChangeTime .. ChangeTime + 24h)
| project TimeGenerated,
          UserPrincipalName,
          AppDisplayName,
          IPAddress,
          ConditionalAccessStatus,
          ConditionalAccessPolicies,
          ResultType,
          ResultDescription
| order by TimeGenerated asc

Which accounts stopped receiving the policy?

Expand ConditionalAccessPolicies and look for the target policy. A result such as notApplied or disabled is not automatically a vulnerability — it can be completely expected depending on scope and policy state — but after an unplanned scope change it becomes a strong investigative signal.
accounts-with-policy-not-applied.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
let PolicyName = "Require MFA for Finance";
SigninLogs
| where TimeGenerated > ago(7d)
| mv-expand Policy = ConditionalAccessPolicies
| extend CAName = tostring(Policy.displayName),
         CAResult = tostring(Policy.result)
| where CAName =~ PolicyName
| where CAResult in~ ("notApplied", "disabled")
| summarize FirstSeen=min(TimeGenerated),
            LastSeen=max(TimeGenerated),
            SignIns=count()
    by UserPrincipalName
| order by SignIns desc

Now count the impact

The phrase “43 accounts became exposed” must come from the evidence, not from assumption. Count the distinct identities whose sign-ins show that the policy was no longer applied after the change window. The actual number will vary by tenant and time range.
affected-account-count.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
let PolicyName = "Require MFA for Finance";
SigninLogs
| where TimeGenerated > ago(7d)
| mv-expand Policy = ConditionalAccessPolicies
| extend CAName = tostring(Policy.displayName),
         CAResult = tostring(Policy.result)
| where CAName =~ PolicyName
| where CAResult in~ ("notApplied", "disabled")
| summarize AffectedAccounts=dcount(UserPrincipalName),
            SignIns=count(),
            FirstSeen=min(TimeGenerated),
            LastSeen=max(TimeGenerated)

Were any of those sign-ins successful?

A policy gap becomes more significant when affected accounts successfully authenticate during the exposure window. Correlate success with source IP, application, risk information and other policies before deciding whether any sign-in represented compromise.
high-risk-successful-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
  18. 18
  19. 19
let PolicyName = "Require MFA for Finance";
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| mv-expand Policy = ConditionalAccessPolicies
| extend CAName = tostring(Policy.displayName),
         CAResult = tostring(Policy.result)
| where CAName =~ PolicyName
| where CAResult in~ ("notApplied", "disabled")
| project TimeGenerated,
          UserPrincipalName,
          AppDisplayName,
          IPAddress,
          RiskLevelDuringSignIn,
          RiskState,
          ConditionalAccessStatus
| order by TimeGenerated desc

“Not applied” needs context

Conditional Access results are easy to overread. A policy can show as not applied because the sign-in did not match the policy conditions. A disabled policy can also appear in the policy evaluation details. The important question is whether the result matches the intended design after the change.
SuccessThe policy was applied successfully to the sign-in.
FailureThe sign-in matched policy scope but did not satisfy the grant controls or was blocked.
Not appliedThe sign-in did not meet the criteria for that policy to apply; whether that is safe depends on the intended scope.

What the evidence can and cannot prove

Audit logs can prove that the policy changed and preserve the actor and modified values. Sign-in logs can show whether the policy was evaluated for real authentication events and what result it returned. Neither alone proves that an attacker exploited the gap. Exposure and exploitation are different findings.
ProvenThe policy changed and affected sign-ins can be identified.
ExposureAccounts outside intended protection represent a control gap.
UnprovenA control gap does not automatically mean an attacker used it.

Agent Foskett's investigation mindset

Do not stop at “the policy was changed.” Ask what changed, who changed it, what the intended scope was, how the sign-in behaviour changed afterwards and whether real accounts were affected. Configuration history becomes security evidence when it is correlated with authentication telemetry.
Follow the changeReconstruct the exact old and new policy values.
Follow the effectMeasure how the policy evaluated against real sign-ins after the change.
Follow the riskDetermine whether exposed accounts had suspicious or successful sign-ins during the window.

Investigation findings

The important discovery was not merely that an administrator changed a Conditional Access policy. The audit trail showed the configuration change, and the sign-in evidence showed that identities that were expected to remain protected were no longer receiving that policy. Forty-three affected accounts turned a routine configuration change into a measurable security exposure.
The policy change was visibleAuditLogs preserved the administrative action and modified values.
The impact was measurableSigninLogs showed which accounts were no longer receiving the expected policy.
Exploitation required separate proofThe control gap had to be investigated without claiming compromise that the evidence did not establish.
One policy changed. Forty-three accounts were now outside the protection everyone thought they still had.
Reconstruct the change, measure the effect and separate exposure from proven exploitation.
Continue the Investigation

Final thought

Conditional Access failures are not always dramatic outages. Sometimes the dangerous change is the one that lets everybody keep working. That is why policy audit history and sign-in evaluation belong in the same investigation: one shows what changed, the other shows what the change actually did.
What changed?Start with AuditLogs and the modified policy values.
Who was affected?Use SigninLogs and ConditionalAccessPolicies to measure scope.
Was the gap exploited?Investigate successful and risky sign-ins separately before reaching that conclusion.
Develop IT. Protect IT.
GEMXIT PTY LTD | GEMXIT UK LTD
Talk to GEMXIT

The Admin Changed One Conditional Access Policy — 43 Accounts Became Exposed

This Agent Foskett investigation explores Microsoft Entra Conditional Access policy changes using AuditLogs, modified properties, SigninLogs, ConditionalAccessStatus, ConditionalAccessPolicies and KQL.

Conditional Access Policy Change Investigation

Learn how to reconstruct who changed a Conditional Access policy, compare the old and new configuration, identify affected sign-ins and determine whether the change created a measurable protection gap.

Microsoft Entra AuditLogs And SigninLogs

Configuration history and authentication telemetry should be correlated so analysts can distinguish a policy change, an exposure and actual exploitation.