Reader Question: How can I set up a “Deny-by-Default” Conditional Access Policy?Alex Fields
It has been a while since I took a question from a reader and turned it into a blog post. It is one of my favorite things to do here on ITProMentor, but the “busy-ness” of life has taken me away from the keyboard a lot in recent months. Now that I am (mostly) settled in a new home, I plan to rekindle some of these old joys.
This one came from Devin, who lives in the U.K.:
Hi Alex, I hope this message finds you well. I watched a recorded presentation of yours where you compared Conditional Access to a “Firewall for the Cloud,” but you mentioned that there are important differences. Specifically, you made the point that most firewalls have a “deny-all” rule by default, and it is up to the administrator to open the inbound ports that are necessary. In Conditional Access, you said it is almost the exact opposite, where everything is open by default, and you have to tell the system what you want closed.
This got me thinking, wouldn’t it be possible to start by creating a “deny-all” rule and then add other rules in front of that, to open the specific applications and access scenarios that you wanted, and no more? Wouldn’t this be more in line with the whole ‘Zero Trust’ concept?
Thanks for your insights!
Great question Devin, and I am glad that you asked it. No analogy is perfect, and it is actually because of these imperfections that the “firewall” comparison can be so illuminating. This will give us the chance to clarify a few things about Azure AD Conditional Access in general, and as well, offer some potential solutions to certain problems.
The first thing to remember is that Conditional Access differs from firewalls in another important way: there is no “ordering” to the rules. I cannot place one rule “in front of” another. All rules are evaluated simultaneously in Conditional Access. So, if I create a rule that says, “Block X,” it does not matter if that rule is located further up or down in my list. It will always be evaluated the same way. “X” will always be blocked.
This also implies that any “block” control always will always win over any “grant” control. Therefore, if I created one rule that said, “Block access to Email” (scoped to All users) and another one that said, “Grant access to email but require MFA” (either scoped to All users, or enabled for a specific security group), then guess what happens? Access is still blocked. In order to get the desired effect with these two policies, you would need to create a security group called something like “Email allowed users” and add that security group to the “Exclude” tab on the Block access… policy.
So, the answer to your question is both yes and no: it is possible to create “Deny-by-default” rules, but not exactly in the way you suggested. But in fact, this type of design (writing explicit block rules for everything then making many exclusions) would be unnecessary for most organizations. I will explain why shortly.
First, just notice that writing your “default deny” rule or rules quickly increases the complexity of your implementation. For example, you would need to manage double the policies and several security groups and exclusions for every access scenario you wanted to open/allow.
- Deny mobile access for all users / Allow mobile access for approved users
- Deny browser access from the desktop / Allow browser access from the desktop
- Deny client app access from the desktop / Allow client app access from the desktop
- Deny access to administrative services / Allow admin access
- Deny all guest access / Allow guest access to approved apps
I think these designs tend to get messy very quickly. You might say, so what? Why not do it this way?
Before we answer that question, let’s take a closer look at one of the other concepts I normally address during my talks on Conditional Access: the two so-called “Architecture types.”
Open (or targeted) architecture: This means targeting your policies to address specific access scenarios. For example: “Require MFA for access to Office 365,” or “Require managed devices for access to Email.” In this architecture, you are putting specific requirements around certain applications or access scenarios, while leaving others “open” or unguarded (i.e.. you do not have policies covering “All cloud apps”).
Closed (or universal) architecture: This means targeting your policies as broadly as possible, for example All users / All cloud apps, e.g.: “Block legacy authentication globally,” or “Require MFA for all users.”
Closed architecture is better aligned to the concepts of Zero Trust since you are not leaving any “holes” or scenarios free of the constraints imposed by the policy. Note that it is also possible to combine these architecture types into a single policy set. For example, you may have a universal requirement for MFA across all cloud apps, but you only require managed devices for access to email, or certain other applications. That is completely fine and up to each individual organization.
Why Closed Architecture is more like Deny-By-Default
Now, let’s assume your goal is ultimate Zero Trust protection across all cloud apps, and that you want to impose both a multi-factor as well as a managed device requirement everywhere. In this case we require multiple policies for various reasons (e.g., easier troubleshooting, better for making more granular exclusions, and covering various access scenarios).
To begin, we need several policies enforcing the MFA requirement:
- Block all legacy authentication: legacy authentication is vulnerable to password spray and replay attacks, and it does not support MFA challenges, so we should eliminate it for all users and all cloud apps.
- MFA required for all admins: it is a best practice to have a policy covering this scenario even if you plan to place the same requirement against all users; that way, if the policy for standard users changes or needs to be temporarily disabled, admins are still protected.
- MFA required for all users: This is your universal MFA requirement for everyone
- MFA to register/join devices: We have a separate “User action” to control this behavior, as it is not covered by the “All cloud apps” selection above.
- Secure the security info registration page: We have a separate “User action” to control this behavior, as it is not covered by the “All cloud apps” selection above. Also, it is recommended to enable the Temporary Access Pass option so that users can still get in to edit authentication methods with help from an administrator, even in the absence of another factor such as a mobile app or hardware token.
- MFA for guests: Note that we can also trust MFA claims from other tenants, so that users are not double-prompted. If you have a policy for the guest access scenario, be sure to modify your default trust settings from Azure AD > External identities > Cross-tenant access settings.
And we need another policy set enforcing device-based requirements, for example:
- Grant mobile access with compliant device, or approved app, or app protection policy: for mobile devices like iOS and Android, you can choose whether to enforce MAM or MDM (or both).
- Grant desktop access with compliant device: we want desktop computers such as Windows and MacOS to be complaint with our policies and managed by the organization.
I suggest that this configuration achieves the “Deny-by-default” posture that we want, without needing to add another “Block” policy on top of it, with additional exceptions, etc. Let me explain why.
When you create a policy with access controls that say, “Grant access” and “Require X, Y or Z” then you could also read this policy as saying, “Access is denied unless X, Y or Z can be met/satisfied.” Therefore, if you do not satisfy MFA, or do no have a managed device, and your policy explicitly says those things are required, then guess what? No access for you!* This is already “deny by default.”
(*By the way, if you target “All cloud apps” with a compliant device requirement, then you must also exclude the Intune enrollment app or else you will be unable to enroll new devices. It’s like a chicken-and-egg problem: you can’t get enrolled in the first place to become evaluated for compliance if there is a compliance requirement in order to get enrolled. Note there may be other impacts as well with other cloud apps when enabling closed policies.)
Additional Deny-by-default rules
Another popular policy set is to have broad “location-based” rules that “deny-by-default” except from approved countries or locations. Example:
- Block access from non-domestic countries: this policy is usually scoped to All cloud apps (closed), with a Block access control placed against All locations, excluding a named location containing the domestic country (e.g. USA, or wherever you live). Optionally, you can also use filters for devices to exclude managed devices (that way you can travel with devices that are already enrolled/managed)
And you can apply this concept to device platforms as well:
- Block device platforms that are not explicitly supported by the organization: in this policy, we block access for all cloud apps on all device platforms, excluding the platforms you intend to support. This has the effect of blocking platforms including ChromeOS, etc. as well.
Let me briefly relate another story that hopefully clarifies the point further. This one combines the concepts of Open architecture with a “Deny-by-Default” policy (for a specific application: email).
Recently a non-profit organization contacted me with a very particular request. They wanted to use Closed architecture for their core policies (i.e., block legacy auth & require MFA), and at the same time use Open architecture for their device-based policies, especially for personal (mobile) devices. The main concern was around corporate email on personal devices. Okay, that’s no problem, and in fact is very common. Here is the catch. They had a very specific on-boarding process whereby a user would not be allowed to gain access to their corporate email using a mobile app until they had completed an E-safety training module. HR would assign them to a security group shortly after passing the exam, and they would thereupon be granted access (but not before then). It was basically a carrot for completing the course material.
They did not want a closed architecture because the scope for this requirement was no wider than email (Exchange Online). However, they still needed a “fail closed” policy set for this application because they did not want a user to gain access on mobile devices before passing the exam. So here is what we did: We implemented the usual policy set for block legacy auth, MFA requirements, etc. Then for the device-based requirement, we only targeted Exchange Online, and used a security group called “Allowed to access email on mobile devices.” We then created two policies:
The first policy was called “Block access to email on mobile devices” and it was configured as follows:
- Users and groups:
Include: All users
Exclude: Allowed to access email + Emergency access accounts
- Cloud apps: Office 365 Exchange Online
- Conditions: Device platform > iOS & Android
- Access controls: Block access
Then the second policy was called “Allow access to email on mobile and desktop apps” and it was configured as follows:
- Users and groups:
Include: All users
- Exclude: Emergency access accounts
- Cloud apps: Office 365 Exchange Online
- Conditions: Client apps > Mobile apps and desktop clients
- Access controls: Grant access w/ Compliant device or Approved App or App protection policy
Remember that all other access scenarios around this application are already covered by our “closed architecture” design for the MFA requirement, etc. This is an additional requirement that says access is granted only when the device is managed (MDM), or the app is protected (MAM), and when the user belongs to the proper security group (indicating they passed the E-safety course).
Now, in my opinion this configuration is not any “safer” or “more secure” than simply deploying the second policy and forgoing the first policy altogether. The reason we deployed both policies wasn’t “because security” or “because deny-by-default,” rather, we did this specifically to enable the custom workflow that they wanted to have, with the training pre-requisite. That’s it.
If your goal is to align your Conditional Access strategy as closely as possible with a ‘Zero Trust’ model, then you should probably be aiming for Closed architecture. However, a closed architecture approach may not be right for every organization and every application/access scenario. Whenever I implement Conditional Access, I always push closed policies for the basics: blocking legacy auth and enforcing MFA. After that, I think it is a good idea to begin evaluating device-based policies with regard to corporate email access specifically, and go further where it makes sense, even all the way to a closed policy set, especially in high-sensitivity or high-security environments. Just be aware there may be other impacts to certain applications (e.g. Intune enrollment, etc.).
Hopefully this cleared up the confusion for you, Devin. Thanks for writing in.