Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Protected Actions Authentication Contexts should have Conditional Access policies

Protected Actions allow organizations to require step-up authentication for sensitive operations by
assigning Authentication Contexts to those actions. However, if an Authentication Context is not
referenced in any Conditional Access policy, the protected action is not effectively protected.

This test verifies that all Authentication Contexts used by Protected Actions are properly referenced
in at least one Conditional Access policy.

## How to fix

If this test fails, you need to create or update Conditional Access policies to reference the Authentication Contexts used by your Protected Actions:

1. Navigate to the [Microsoft Entra admin center](https://entra.microsoft.com)
2. Go to **Protection** > **Conditional Access** > **Policies**
3. Create a new policy or edit an existing one
4. Under **Target resources** > **Authentication context**, select the Authentication Context(s) that need to be protected
5. Configure the appropriate grant controls (e.g., require authentication context, require compliant device)
6. Enable the policy and save

Alternatively, if the Protected Action no longer needs step-up authentication, you can remove the Authentication Context assignment from the Protected Action:

1. Navigate to the [Microsoft Entra admin center](https://entra.microsoft.com)
2. Go to **Identity** > **Roles & admins** > **Protected actions (Preview)**
3. Select the Protected Action
4. Remove or update the Authentication Context assignment

## Learn more

- [Protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-overview)
- [Conditional Access: Target resources](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps)
- [Authentication context in Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps#authentication-context)

## Related links

- [Entra admin center - Conditional Access Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Overview/fromNav/)
- [Entra admin center - Authentication contexts](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthenticationContext)
- [Entra admin center - Protected actions](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/ProtectedActions)

<!--- Results --->
%TestResult%
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<#
.Synopsis
Checks if all Protected Actions Authentication Contexts have a conditional access policy referenced.

.Description
Protected Actions allow organizations to require step-up authentication for sensitive operations by
assigning Authentication Contexts to those actions. However, if an Authentication Context is not
referenced in any Conditional Access policy, the protected action is not effectively protected.

This test verifies that all Authentication Contexts used by Protected Actions are properly referenced
in at least one Conditional Access policy.

Learn more:
https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-overview

.Example
Test-MtCaAuthContextProtectedActionsExist

.LINK
https://maester.dev/docs/commands/Test-MtCaAuthContextProtectedActionsExist
#>
function Test-MtCaAuthContextProtectedActionsExist {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Exists is not a plural.')]
[CmdletBinding()]
[OutputType([bool])]
param ()

if ( ( Get-MtLicenseInformation EntraID ) -eq 'Free' ) {
Add-MtTestResultDetail -SkippedBecause NotLicensedEntraIDP1
return $null
}

try {
# Get all authentication contexts
$authContexts = Invoke-MtGraphRequest -RelativeUri 'identity/conditionalAccess/authenticationContextClassReferences' -ApiVersion beta

if (-not $authContexts -or ($authContexts | Measure-Object).Count -eq 0) {
$testResult = 'No Authentication Contexts are configured in the tenant.'
Add-MtTestResultDetail -Result $testResult
return $true
}

# Get the role management policy assignments to find protected actions
# Protected Actions are configured through PIM policies
$pimPolicies = Invoke-MtGraphRequest -RelativeUri 'policies/roleManagementPolicyAssignments' -ApiVersion beta -Filter "scopeId eq '/' and scopeType eq 'Directory'" -ErrorAction SilentlyContinue

# Collect all auth context IDs that are used in protected actions
$authContextsInProtectedActions = [System.Collections.Generic.HashSet[string]]::new()

# Check role management policies for protected actions configuration
if ($pimPolicies) {
foreach ($assignment in $pimPolicies) {
try {
$policyDetails = Invoke-MtGraphRequest -RelativeUri "policies/roleManagementPolicies/$($assignment.policyId)" -ApiVersion beta -ErrorAction SilentlyContinue
if ($policyDetails.rules) {
foreach ($rule in $policyDetails.rules) {
if ($rule.'@odata.type' -eq '#microsoft.graph.unifiedRoleManagementPolicyAuthenticationContextRule' -and $rule.isEnabled -and $rule.claimValue) {
[void]$authContextsInProtectedActions.Add($rule.claimValue)
}
}
}
} catch {
Write-Verbose "Could not retrieve policy details for $($assignment.policyId): $_"
}
}
}

# Get all enabled conditional access policies
$caPolicies = Get-MtConditionalAccessPolicy | Where-Object { $_.state -eq 'enabled' }

# Collect all auth context IDs referenced in CA policies
$authContextsInCAPolicies = [System.Collections.Generic.HashSet[string]]::new()
foreach ($policy in $caPolicies) {
if ($policy.conditions.applications.includeAuthenticationContextClassReferences) {
foreach ($context in $policy.conditions.applications.includeAuthenticationContextClassReferences) {
[void]$authContextsInCAPolicies.Add($context)
}
}
}

# Check for auth contexts that are used in protected actions but not in CA policies
$unprotectedContexts = [System.Collections.Generic.List[object]]::new()

foreach ($id in $authContextsInProtectedActions) {
if (-not $authContextsInCAPolicies.Contains($id)) {
$ctx = $authContexts | Where-Object { $_.id -eq $id } | Select-Object -First 1
$unprotectedContexts.Add(@{
Id = $id
DisplayName = if ($ctx) { $ctx.displayName } else { '(Deleted or not found)' }
Description = if ($ctx) { $ctx.description } else { '' }
IsAvailable = if ($ctx) { $ctx.isAvailable } else { $null }
})
}
}

# Determine result
$result = $unprotectedContexts.Count -eq 0

if ($result) {
if ($authContextsInProtectedActions.Count -eq 0) {
$testResult = 'No Authentication Contexts are configured for Protected Actions in this tenant.'
} else {
$testResult = "All Authentication Contexts used in Protected Actions are properly referenced in Conditional Access policies.`n`n"
$testResult += "**Protected Action Auth Contexts with CA policies:**`n`n"
foreach ($authContext in $authContexts) {
if ($authContextsInProtectedActions.Contains($authContext.id)) {
$testResult += "- $($authContext.displayName) ($($authContext.id))`n"
}
}
}
} else {
$testResult = "The following Authentication Contexts are used in Protected Actions but are not referenced by any Conditional Access policy:`n`n"
$testResult += "| Authentication Context | ID | Description |`n"
$testResult += "| --- | --- | --- |`n"
foreach ($context in $unprotectedContexts) {
$displayName = if ($context.DisplayName) { $context.DisplayName } else { "(No name)" }
$description = if ($context.Description) { $context.Description } else { "(No description)" }
$testResult += "| $displayName | $($context.Id) | $description |`n"
}
$testResult += "`n`n⚠️ **Warning**: These Protected Actions are not effectively protected because their Authentication Contexts are not enforced by any Conditional Access policy.`n"
}

Add-MtTestResultDetail -Result $testResult
return $result

} catch {
Add-MtTestResultDetail -SkippedBecause Error -SkippedError $_
return $null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
Test-MtCaApprovedClientApp | Should -Be $true -Because "no policy use the deprecated Approved Client App grant."
}

It "MT.1106: All Protected Actions Authentication Contexts should be referenced by a Conditional Access policy. See https://maester.dev/docs/tests/MT.1106" -Tag "MT.1106" {
Test-MtCaAuthContextProtectedActionsExist | Should -Be $true -Because "all Authentication Contexts used in Protected Actions should be enforced by Conditional Access policies."
}

Context "Maester/Entra" -Tag "Entra", "License" {
It "MT.1022: All users utilizing a P1 license should be licensed. See https://maester.dev/docs/tests/MT.1022" -Tag "MT.1022" {
$LicenseReport = Test-MtCaLicenseUtilization -License "P1"
Expand Down
49 changes: 49 additions & 0 deletions website/docs/tests/maester/MT.1106.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: MT.1106 - All Protected Actions Authentication Contexts should be referenced by a Conditional Access policy
description: This test checks if all Authentication Contexts used in Protected Actions are properly referenced in at least one Conditional Access policy.
slug: /tests/MT.1106
sidebar_class_name: hidden
---

# Protected Actions Authentication Contexts should have Conditional Access policies

## Description

Protected Actions allow organizations to require step-up authentication for sensitive operations by assigning Authentication Contexts to those actions. However, if an Authentication Context is not referenced in any Conditional Access policy, the protected action is not effectively protected.

This test verifies that all Authentication Contexts used by Protected Actions are properly referenced in at least one Conditional Access policy.

When a Protected Action has an Authentication Context assigned but that context is not enforced by any Conditional Access policy:
- Users will not be prompted for additional authentication when performing the protected action
- The security benefit of the Protected Action is lost
- The tenant may be exposed to unauthorized sensitive operations

## How to fix

If this test fails, you need to create or update Conditional Access policies to reference the Authentication Contexts used by your Protected Actions:

1. Navigate to the [Microsoft Entra admin center](https://entra.microsoft.com)
2. Go to **Protection** > **Conditional Access** > **Policies**
3. Create a new policy or edit an existing one
4. Under **Target resources** > **Authentication context**, select the Authentication Context(s) that need to be protected
5. Configure the appropriate grant controls (e.g., require authentication context, require compliant device)
6. Enable the policy and save

Alternatively, if the Protected Action no longer needs step-up authentication, you can remove the Authentication Context assignment from the Protected Action:

1. Navigate to the [Microsoft Entra admin center](https://entra.microsoft.com)
2. Go to **Identity** > **Roles & admins** > **Protected actions (Preview)**
3. Select the Protected Action
4. Remove or update the Authentication Context assignment

## Learn more

- [Protected actions in Microsoft Entra ID](https://learn.microsoft.com/entra/identity/role-based-access-control/protected-actions-overview)
- [Conditional Access: Target resources](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps)
- [Authentication context in Conditional Access](https://learn.microsoft.com/entra/identity/conditional-access/concept-conditional-access-cloud-apps#authentication-context)

## Related links

- [Entra admin center - Conditional Access Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Overview/fromNav/)
- [Entra admin center - Authentication contexts](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/AuthenticationContext)
- [Entra admin center - Protected actions](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/ProtectedActions)
Loading