Conditional Access Policies¶
Conditional Access is the policy engine that gates access to Microsoft 365 resources based on signals such as user identity, device state, location, and risk level.
Prerequisites
- Entra ID P1 licence for all users (included in Microsoft 365 Business Premium, E3, E5)
- Break-glass accounts created and excluded from every policy before any policy goes live
- Authentication Strengths created before creating the MFA enforcement policies (see MFA & Authentication)
- Named location Approved Countries created before creating the Geoblock policy
- Security group Overseas Travel created before creating the Geoblock policy
Break-Glass Accounts¶
Create two emergency access accounts and exclude them from every CA policy. If a misconfigured policy locks out all admins, these accounts are the only recovery path.
- Cloud-only accounts — not synced from on-premises AD
- Named clearly:
breakglass1@domain.com,breakglass2@domain.com - Long, randomly generated passwords stored in a sealed envelope and a password manager
- FIDO2 hardware security key registered as the only auth method (no Authenticator app)
- No roles assigned permanently — activate via PIM only when needed
- Alert rule in place to notify security team on any sign-in
Pre-Configuration¶
Named Location — Approved Countries¶
Create this before Policy 5 (Geoblock).
Entra admin center → Protection → Conditional Access → Named locations → + Countries location
| Setting | Value |
|---|---|
| Name | Approved Countries |
| Determine location by | Country or region based on IP address |
| Countries | Add all countries users legitimately sign in from (e.g., Australia, New Zealand, United Kingdom) |
| Include unknown countries/regions | No |
Security Group — Overseas Travel¶
Create this group in Entra ID before Policy 5 (Geoblock).
Entra admin center → Groups → New group
| Setting | Value |
|---|---|
| Group type | Security |
| Group name | Overseas Travel |
| Membership type | Assigned |
| Description | Members excluded from the Geoblock CA policy while travelling internationally |
Add users to this group when they notify IT of upcoming travel. Remove them on return.
Tip
Consider a lifecycle process: set a group member expiry using a time-limited access package in Entitlement Management (requires Entra ID P2), so membership auto-expires after the travel period without manual cleanup.
Policies¶
CA001 — Enforce 2FA for All Users¶
Purpose: Require all users to complete MFA using an approved authentication method before accessing any cloud app.
MFA is enforced through Authentication Strength rather than the basic "Require MFA" grant — this gives precise control over which methods are accepted.
| Setting | Value |
|---|---|
| Name | CA001 - Enforce 2FA for All Users |
| Users | All users |
| Exclude | Break-glass accounts, Guests (handle separately if needed) |
| Target resources | All cloud apps |
| Conditions | None |
| Grant | Require authentication strength: Standard MFA (custom strength — see Authentication Strengths) |
| State | On |
Standard MFA strength allows:
- Microsoft Authenticator (push notification + number match)
- Windows Hello for Business
- FIDO2 security key / Passkey
- Temporary Access Pass (one-time or multi-use)
CA002 — Enforce 2FA for Admins¶
Purpose: Apply a stricter authentication strength to privileged directory roles. Admins are the highest-value targets — this policy ensures they can only use methods appropriate for sensitive accounts.
This policy targets specific roles rather than a group, so it automatically catches any new admin role assignments.
| Setting | Value |
|---|---|
| Name | CA002 - Enforce 2FA for Admins |
| Users — Include | Directory roles: Global Administrator, Exchange Administrator, SharePoint Administrator, Teams Administrator, User Administrator, Helpdesk Administrator, Security Administrator, Security Operator, Compliance Administrator, Billing Administrator, Privileged Role Administrator, Privileged Authentication Administrator |
| Exclude | Break-glass accounts |
| Target resources | All cloud apps |
| Conditions | None |
| Grant | Require authentication strength: Admin MFA (custom strength — see Authentication Strengths) |
| State | On |
Admin MFA strength allows everything in Standard MFA, plus:
- Software OATH token (e.g., hardware token app generating TOTP codes)
Note
CA002 takes precedence over CA001 for admin accounts because it requires a named strength. If a user is both a standard user and an admin, the more restrictive policy (CA002) wins.
CA003 — Block Legacy Authentication¶
Purpose: Block authentication protocols that cannot perform MFA — SMTP AUTH, IMAP, POP3, Exchange ActiveSync (basic auth), and other legacy clients. These protocols are a primary vector for credential stuffing attacks.
Run in Report-only first
Before enforcing, check for legacy auth usage. Entra admin center → Monitoring → Sign-in logs → filter Client app = Exchange ActiveSync, Other clients, IMAP, POP3, SMTP. Run Report-only for at least 2 weeks and investigate any hits before switching On.
| Setting | Value |
|---|---|
| Name | CA003 - Block Legacy Authentication |
| Users | All users |
| Exclude | Break-glass accounts |
| Target resources | All cloud apps |
| Conditions → Client apps | Exchange ActiveSync clients + Other clients |
| Grant | Block access |
| State | Report-only → On after verification |
CA004 — Block Device Code Flow¶
Purpose: Block the OAuth 2.0 device authorization grant (device code flow). This flow is exploited in phishing attacks where an attacker sends a victim a code to enter at microsoft.com/devicelogin, authenticating as the victim without needing their credentials.
| Setting | Value |
|---|---|
| Name | CA004 - Block Device Code Flow |
| Users | All users |
| Exclude | Break-glass accounts |
| Target resources | All cloud apps |
| Conditions → Authentication flows | Device code flow |
| Grant | Block access |
| State | On |
Where to find Authentication flows
Conditions → Authentication flows is a relatively new CA condition. If you don't see it, ensure your tenant is on the current Entra admin center experience. The setting is: Conditions → Authentication flows → Configure → Device code flow → Yes.
Exceptions
If any legitimate device (e.g., an IoT device, shared terminal, or Azure CLI workflow) requires device code flow, create a separate named group (Device Code Flow Allowed) and exclude it from this policy with documented approval.
CA005 — Geoblock — Approved Countries Only¶
Purpose: Block sign-ins from any country not in the Approved Countries named location. Staff travelling internationally can be added to the Overseas Travel security group to temporarily bypass this policy.
| Setting | Value |
|---|---|
| Name | CA005 - Geoblock - Approved Countries Only |
| Users — Include | All users |
| Users — Exclude | Break-glass accounts, Group: Overseas Travel |
| Target resources | All cloud apps |
| Conditions → Locations — Include | Any location |
| Conditions → Locations — Exclude | Named location: Approved Countries |
| Grant | Block access |
| State | Report-only → On after verification |
Run in Report-only first
Before enforcing, review Entra admin center → Sign-in logs and filter by location to confirm no legitimate users are signing in from countries not in your approved list. Watch for VPN exit nodes, cloud sync services, and third-party app integrations that may originate from unexpected countries.
Overseas Travel process¶
When a user notifies IT of international travel:
- Add the user to the Overseas Travel group in Entra ID
- Confirm the policy exclusion is active (sign-in should succeed from destination)
- Set a calendar reminder to remove them on their return date
- On return, remove from the group
# Add a user to the Overseas Travel group
Connect-MgGraph -Scopes "GroupMember.ReadWrite.All"
$groupId = (Get-MgGroup -Filter "displayName eq 'Overseas Travel'").Id
$userId = (Get-MgUser -Filter "userPrincipalName eq 'user@domain.com'").Id
New-MgGroupMember -GroupId $groupId -DirectoryObjectId $userId
# Remove after travel
Remove-MgGroupMemberByRef -GroupId $groupId -DirectoryObjectId $userId
Policy Deployment Order¶
Deploy in this sequence to avoid locking users out before break-glass and exclusions are in place:
flowchart LR
A[1. Create break-glass accounts] --> B[2. Create Authentication Strengths]
B --> C[3. Create Named Locations + Overseas Travel group]
C --> D[4. Deploy CA001–CA004 in Report-only]
D --> E[5. Deploy CA005 in Report-only]
E --> F[6. Review sign-in logs 2+ weeks]
F --> G[7. Enable CA003 + CA004 — low risk]
G --> H[8. Enable CA001 + CA002]
H --> I[9. Enable CA005 last] Monitoring¶
Entra admin center → Monitoring → Workbooks → Conditional Access Insights and Reporting
This workbook shows policy impact, sign-in success/failure counts, and which policy is enforcing or blocking for each sign-in — essential for validating Report-only mode before going live.
Useful PowerShell¶
Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess","Policy.Read.All"
# List all CA policies with state
Get-MgIdentityConditionalAccessPolicy |
Select-Object DisplayName, State, Id |
Sort-Object DisplayName
# Export all policies to JSON (good for documentation / disaster recovery)
Get-MgIdentityConditionalAccessPolicy |
ConvertTo-Json -Depth 10 |
Out-File "CA-Policies-$(Get-Date -Format yyyyMMdd).json"
# Find sign-ins blocked by a specific CA policy (requires Graph Reports scope)
Connect-MgGraph -Scopes "AuditLog.Read.All"
Get-MgAuditLogSignIn -Filter "conditionalAccessStatus eq 'failure'" -Top 50 |
Select-Object UserDisplayName, UserPrincipalName, CreatedDateTime, IpAddress,
@{N="CAPolicies";E={ ($_.AppliedConditionalAccessPolicies | Where-Object { $_.Result -eq "failure" }).DisplayName -join ", " }}