How to manage and secure service accounts in Microsoft Office 365 (without MFA)
Okay, so hopefully everyone knows by now that MFA is not an “optional” thing that you can decide to turn on, or not, depending on your “feelings.” It isn’t a choice, and your feelings about it don’t matter. You need to turn it on. I would recommend requiring MFA at least on unmanaged devices.
Again, this is minimum. But… what about service accounts?
The service account problem
Service accounts are accounts that do not have an actual “person” behind them–usually they represent some kind of device or application that needs to perform specific tasks in your Office 365 tenant. Common examples include some type of copier/scanner device that sends mail from an account like “[email protected].” Or, a backup account that needs to access the environment to read data out–placing a copy of mailboxes and/or files in some third party’s cloud location.
Now, some apps and services out there have modernized their approach to this problem, and if they need to integrate with Office 365, they will have you setup an App registration, and use OAuth to grant consent so that the app can do what it needs to do, without using a password to sign-in.
So if you’re working with a modern app that supports OAuth, then you can just take this route, and follow their guidance for setting it all up. Here is one example for reference, from an app called LionGard Roar, which I have configured to ingest certain data from Office 365. Please note that instructions for configuring this registration will vary by application, so it is best to find out if your vendor supports this setup and follow their documentation carefully from there.
But here’s the problem: hardly any applications or devices out there on the market today support the App registration / OAuth consent method. Almost everyone who is attaching to Office 365 services is doing so with basic authentication (which does not support MFA)–so it’s just a straight username and password.
And that sucks. Especially for backup accounts which often have full access to read all data in a tenant (and many people are setting this up with Global admin rather than something more restrictive). Or even SMTP accounts that can send mail on behalf of the organization. So if you can’t use MFA on these types of accounts, what should you do?
Solution #1: App passwords
A common solution is to enable MFA on the account anyway, but then use an app password, which is a randomly generated string of 16 lowercase letters (you cannot change or manually set this password anywhere–but you can go generate new ones from the “My Account” page).
They are basically just an MFA bypass for apps that do not support modern authentication. As a bridge off of legacy apps, they were necessary, but now that most people have moved on to Office 365 Business and ProPlus apps, it’s time to shut them down.
Solution #2: Only allow service account sign-in from specified locations
Remember that an app password is essentially just an MFA bypass for basic authentication clients. So, why even enable MFA on this account? After all, the user (which is some machine somewhere) cannot perform MFA–it’s just going to use the bypass anyway, right? Therefore, why not set your own long, randomly generated password for this account?
Bonus: did you know that the password character limit in Azure AD was recently increased to 256 characters? So go crazy, have fun, and make up your own “super app password” using a generator like this one:
Your character limit might be bounded by the application or service itself sometimes (i.e. how big is the field where they accept a password?). But you get the idea–you aren’t held to 16, all lowercase letters.
Now, a long password is a good start, but what else can we do?
Before we get started on the solution, be sure that you include this service account in a security group called “Excluded from CA policies.” In general this group will contain at least one emergency access/ break-glass admin account, as well as any service accounts that cannot be subject to other Conditional Access policies, like those which require MFA (remember that service accounts do not support MFA). Make sure that the group “Excluded from CA policies” is added to the Exclude tab on all of your existing Conditional Access policies.
Next, we need to obtain the IP addresses that the service account is using. For on-premises applications and devices like copier/printer/scanners that need SMTP access, this is easy–it’s just the external IP addresses on your corporate firewall. But, if you have this setup and working now with basic auth–either via app password or straight password, then go take a look at the Azure AD Sign-in logs.
NOTE: You will want at least one subscription of Azure AD Premium in the tenant to view detailed logs.
Here you can filter by the user account, and find the IP address(es) associated with these sign-ins. Or you might consider contacting your vendor if the app or service is hosted with them–they might be able to give you IP blocks also.
Once you have collected the IP addresses, go to Azure AD > Conditional Access > Named locations. Create a named location for this app vendor or device’s location. Click New location.
Simply specify a name and IP range(s) using CIDR format.
Now construct your Conditional access policy like this:
- Name it something descriptive like BLOCK – <service account name> access from unknown locations
- Under Assignments > Users and groups target this policy specifically to the one user account that is being used by this device or application
- Target All cloud apps
- Under Access controls choose Block access
Back under Conditions > Location, pick Any location under the Include tab, and then under Exclude, choose the specific named location that you created above.
Save and enable the policy. Again this account will be excluded from any other conditional access requirement (e.g. MFA, compliant device, etc.), yet only be able to sign-in from the specified locations.
In my opinion, this combo is stronger than app passwords–you have a longer random password, and access is restricted by IP.
Password mitigation: now and in the future
Let’s just briefly discuss what you are protecting against with this configuration: (1) credential theft and (2) brute force attacks. App passwords, like any password, can be discovered and ex-filtrated. In that case you need to revoke the app password you have, and create a new one (assuming you even know that the account has been compromised to begin with). But with Conditional access, the password can only be used from the specified location, so if that random string “gets out there” it won’t be as much of a threat.
As regards the brute force thing, although unlikely, it could happen. If not now, perhaps in the future. After all, cracking 2048-bit RSA encryption takes a quantum computer a matter of minutes, a task which takes traditional computers far longer (~1 billion years).
So although brute force isn’t a popular method used by bad guys right now (password spray is far more common–e.g. attempting very common passwords against a large number of accounts), that preference might not always be the case. I assume that we’ll have to leave passwords behind at some point here before quantum computing “happens.” And on top of that, move to some post-QC encryption standards.
Nevertheless, you can see why Microsoft, who is also working toward enterprise QC, wants to kill passwords. All of the ridiculous mitigation we have for passwords now just wouldn’t need to exist in a passwordless world. But you know what? Even in that world, I’d still feel better with some strong Conditional Access policies in place. Just as I do today, even with MFA turned on.
So there you have it, my thoughts on this topic in a nutshell. Went longer than expected. But I hope you find it useful information.
Comments (10)
I think a good service account to call out and frequently used is the cloud GA account that is needed to configure Azure AD connect.
Another great article and a simple no-brainer really. We have MFA in place for user admin accounts, but not for the service accounts. Putting in a conditional access policy like this, with location restrictions is simple and one that i will start to put in place straight away. Service accounts only ever really use the same known IPs and so this should be ideal and closes that security hole quickly and easily.
On the same subject, I’ve been checking our “administrator” accounts in 365 and we seem to have three unfamiliar non-user admin accounts, all referencing the Role of “Directory synchronization accounts”.
When checking “Roles and administrators” in Azure AD, this particular role is not listed which seems strange.
They all have a “Name” of “On-Premises Directory Synchronization Service Account”, with different “User names” starting with “Sync_”
Only one of the 3 accounts has any “sign-ins” in the last 30 days, and this one account signs-in every 30 mins.
I’m guessing these accounts are all related to synchronization between our on-prem AD and Azure AD.
Do you think I should just leave these accounts alone? Im thinking about disabling the two that don’t have any sign-ins, and for the one that is currently signing-in, should I include this in creating a conditional access policy, tying it down to the IP that it is using? Which looks like a Microsoft Azure IP (which has remained constant over the last 30 days).
One reason that at least implementing app passwords on these service accounts is better than nothing is that it means you have enabled MFA on the account. So if an attacker does gain access through the regular documented service account password with modern authentication, they will be prompted for MFA and fail to login. If they try to access a legacy protocol like IMAP, the regular password will not allow them in and they will have to provide the app password, which they will not have unless they spend many years on a brute force attack. It does mean that you should not store or document the app password though for anyone to find. Consider it to be one-time use. If you are making system changes, you will need to generate a new app password. Overall, implementing MFA on service accounts with an app password is a huge step up from the default settings for clients that don’t have Azure AD Premium licenses with Conditional Access.
I do agree on shutting down app passwords with Conditional Access when possible, but for many clients, it is not yet practical due to application limitations and not owning the licenses to allow them to do it. Limiting to specific locations is even better. In the absence of that, I will take the MFA with App Password method to make a huge leap in security improvement for the account.
Yep, and it is listed as solution #1–po’ man’s solution. I just like solution #2 better.
Hi
Thanks for this article. Can I just ask what is possibly a silly question? In report only mode, how would this show up for the included accounts to show that when applied for real that they would be able to access? I am seeing under grant controls BLOCK and under Result Report-only: Not applied. Is this correct?
What shows up under the report only is what would happen in real life, with it turned on. So for example if you are excluding a certain account from a policy that BLOCKS access, then the report only should show that the policy is not applied–that would be right. If they were not excluded from the policy then the result there should be that the policy was applied and access blocked.
I’m not sure I’d feel comfortable that an IP restriction actually gives us that much security. If we fall back to the classic 3-tier concepts, service accounts are typically only used communicating within or cross tiers, so most ACLs/firewalls already account for this (app tier only gets traffic from the web tier, thus the firewall/acl is already configured to reject anything else). Modern service meshes follow this as well, just automating the FW sidecar for the admin. Therefore adding this as an MFA step doesn’t really _add_ anything. In classic 3Tier the firewall already does this, in modern container strategies the service mesh does.
If we assume breach (classic security stance), then traffic is already coming from the trusted IP in pretty much all but the most extreme edge cases (internal API accidentally exposed to public traffic), thus 2nd factor is met, and the net gain here is … nearly zero. While I think enabling MFA is a good idea to kill interactive login attempts, I don’t think Id be comfortable stating that an IP range would be an effective improvement over app passwords. Rather, if we are concerned about app passwords being “too static”, id rather introduce an automated password rotation of some kind, as it just doesn’t “feel” like you’re actually adding anything. Or maybe I’m over thinking it…
I was reading the MS KB about setting up a break glass account and they suggest setting up an e-mail alert for when the account authenticates but this seems to require Azure AD Analytics. Does anyone know of another way to setup an authentication alert that will not require licensing above Business Premium?
Sentinel or MCAS can be added to any subscription at a very low cost…but not native in BP.