For the complete documentation index, see llms.txt. This page is also available as Markdown.

AZ_CAP_DUPLICATE_OF

Summary

Forestall ACL Alias

AZ_CAP_DUPLICATE_OF

Entra ID (Azure AD) Alias

Conditional Access Policy - Exact Duplicate

Affected Object Types

Conditional Access Policy <-> Conditional Access Policy

Edge Direction

Symmetric (one edge per unordered pair, queried undirected)

Exploitation Certainty

Informational

Description

AZ_CAP_DUPLICATE_OF connects two Conditional Access Policies (AZConditionalAccessPolicy) in the same tenant that are exact duplicates of each other: identical conditions, grant controls, and session controls after normalization. Policy name, state (enabled / disabled / report-only), and timestamps are deliberately ignored, so a report-only or disabled clone of an enforced policy still counts as a duplicate. That is the most common real-world case: a policy cloned for testing and never removed.

The edge is symmetric. One edge is written per unordered pair (the collector writes it from the ordinally smaller policy Guid to the larger) and it is meant to be queried undirected. Each policy in a duplicate group also carries DuplicateCount, DuplicateGroupId (the first eight characters of the group's canonical hash), and DuplicateOf (the peer Guids).

This edge is informational and hygiene-focused, not an attack primitive. Duplicate policies inflate the policy set, make Conditional Access harder to reason about, and cause drift when one copy is updated and the others are not, which can quietly weaken enforcement.

Identification

PowerShell (Microsoft Graph)

Duplicate detection compares the full condition and control set. A practical approximation is to hash the comparable fields and group by the hash:

Connect-MgGraph -Scopes "Policy.Read.All"

Get-MgIdentityConditionalAccessPolicy -All | ForEach-Object {
    $key = ($_ | Select-Object -ExpandProperty Conditions | ConvertTo-Json -Depth 10) +
           ($_ | Select-Object -ExpandProperty GrantControls | ConvertTo-Json -Depth 10) +
           ($_ | Select-Object -ExpandProperty SessionControls | ConvertTo-Json -Depth 10)
    [PSCustomObject]@{ Name = $_.DisplayName; State = $_.State; Key = $key }
} | Group-Object Key | Where-Object Count -gt 1 |
  ForEach-Object { $_.Group | Select-Object Name, State }

Azure Portal

  1. Open Microsoft Entra admin center -> Protection -> Conditional Access -> Policies.

  2. Compare policies with the same assignments, conditions, and controls; look for clones left in report-only or disabled state.

Exploitation

There is no exploit for this edge; it flags redundant Conditional Access configuration. Its value is operational hygiene: duplicates should be consolidated so there is one authoritative policy per intent, reducing the chance that an update to one copy leaves the others enforcing stale rules.

Mitigation

  • Consolidate exact duplicates into a single authoritative policy and remove the clones.

  • Remove test clones once testing is complete rather than leaving them disabled or in report-only.

  • Adopt a naming and lifecycle convention for Conditional Access policies to prevent accidental duplication.

Detection

Use the Microsoft Entra admin center:

  1. Open Microsoft Entra ID -> Audit logs and filter for Conditional Access policy creation.

  2. Review newly created policies against existing ones for identical conditions and controls.

  3. Periodically review the full policy set for redundant entries, especially disabled or report-only clones.

References

Last updated

Was this helpful?