Conditional Access
Conditional Access is the Microsoft Entra ID policy engine that evaluates every sign-in and decides whether to allow it, require more proof or block it. The Azure Enterprise Baseline defines its multifactor authentication (MFA) and session rules as Conditional Access policies in code, in report-only mode until the reports show they are safe to enforce.
What it does
A Conditional Access policy has assignments (which users, groups or directory roles, which applications, which client types) and controls: grant controls such as requiring MFA, an authentication strength such as phishing-resistant MFA, or blocking access; and session controls such as how often a user must sign in again. Every policy has a state: enabled, disabled or report-only (enabledForReportingButNotEnforced), in which Entra evaluates the policy and records the result in the sign-in logs without acting on it. Conditional Access needs Microsoft Entra ID P1.
How BuiltForProd uses it
The conditional-access unit in acme-core-identity creates up to five policies (modules/conditional-access/main.tf):
| Policy | Who | Control |
|---|---|---|
CA001-require-mfa-all-users | All users, all applications | Require MFA |
CA002-block-legacy-authentication | All users, Exchange ActiveSync and other legacy clients | Block |
CA003-privileged-roles-phishing-resistant | Global Administrator, Privileged Role Administrator, Security Administrator, and the ACME_PlatformLeads and ACME_DevOpsLeads groups | Phishing-resistant MFA, sign-in again every 12 hours |
CA004-require-mfa-azure-management | All users, the Windows Azure Service Management API (portal, CLI, Resource Manager) | Require MFA |
CA005-vpn-sign-in-frequency (optional) | All users, the Azure VPN client application | Require MFA, sign-in again every 8 hours |
CA005 exists only with enable_vpn_sign_in_frequency_policy = true, set together with the point-to-site VPN. Directory roles are looked up by display name in the role templates, so no role identifier is written in code.
Report-only first. One variable sets the state of every policy, and the unit keeps its report-only default:
variable "conditional_access_state" {
description = "State of every policy: enabledForReportingButNotEnforced (report-only), enabled or disabled."
type = string
default = "enabledForReportingButNotEnforced" # @optional: "enabled" once the report-only results are clean
validation {
condition = contains(["enabledForReportingButNotEnforced", "enabled", "disabled"], var.conditional_access_state)
error_message = "The conditional_access_state must be enabledForReportingButNotEnforced, enabled or disabled."
}
}
The policies stay in enabledForReportingButNotEnforced until the report-only results in the sign-in logs show that no legitimate sign-in would be blocked; then the value becomes "enabled" through a pull request. Because the Entra sign-in logs reach the audit workspace, those results can be queried there.
Break-glass exclusion. Every policy excludes ACME_BreakGlass, so the emergency accounts can still sign in if a policy or an MFA provider fails. The exclusion is watched instead of trusted: a KQL (Kusto Query Language) alert on the audit workspace in Log Analytics, part of the cis-alerts unit, fires at severity 0 on any sign-in by an account whose name starts with acme-breakglass-, and another alert fires on any change to a Conditional Access policy. Both route to the ag-acme-security-alerts action group. Break-glass accounts can also activate Owner at mg-acme through Privileged Identity Management when it is on.
Terms you will see
| Term | Meaning |
|---|---|
| Report-only | The state in which a policy is evaluated and logged but not enforced. |
| Grant control | What a sign-in must satisfy: MFA, an authentication strength, or nothing (block). |
| Authentication strength | A named set of allowed methods; "phishing-resistant MFA" allows FIDO2, Windows Hello for Business and certificates. |
| Sign-in frequency | How often a session must authenticate again. |
| Legacy authentication | Protocols that cannot do MFA, such as Exchange ActiveSync and basic authentication. |
| Break-glass account | An emergency account outside Conditional Access, alerted on every use. |
Where to read more
- Azure Enterprise Baseline overview for the identity units.
- Microsoft Entra ID for the groups and the log export.
- Defense in depth for how sign-in policy layers with RBAC and Azure Policy.