Third-Party Microsoft Partner Vendor disallows MFA and Azure Security Defaults
I'm in a big bind. Skykick is a migration and cloud backup tool for Office 365 we've been using. They're a Microsoft partner and offered IUR licenses via Microsoft Partner Center a year or two ago. I recently enabled the Azure Security Defaults and my backups are no longer working. When I contacted them, they replied:
We understand the security concerns are a big factor in why Microsoft has implemented these conditions into their contracts and it's why we are working hard on making this solution our highest priority.
Additionally, we're aware of the Azure Security Defaults. Those can be disabled as they are an issue we run into with migrations and have to deal with them frequently. Unfortunately, it does not change the fact that right now, we require MFA to be off on the Global Administrator and the Azure Security Defaults to be disabled.
If they can safely be shut off within the conditions of your contract, we will then be able to perform snapshots and restores.
- What can I do here?
Partner to Partner
1. Ask SkyKick when they will provide a more secure way of authenticating (not using username & password of a global admin, but using a token based approach similar to the secure app model).
2. In the meantime - use a different method for enabling MFA. If this is about the Partner tenant, note that you can not fulfill the contractual requirement to have all user accounts protected with MFA if you exclude this user account, but given the current plan of technical enforcement there will not be a direct impact since the account used SkyKick will not directly access Partner Center and not your customers: https://docs.microsoft.com/en-us/partner-center/partner-security-requirements-mandating-mfa (You can try to request for technical exception as mentioned in the article, but since SkyKick will not be hit by the technical enforcement since it does not access Partner Center, it will likely not be granted)
And also I would recommend to use a distinct account for SkyKick with a strong password, so that the normal Global Admin used used in day-to-day work can be proteced with MFA.
Of course, to use different methods for MFA, you need to have licenses, e.g. AzureAD Premium Plan1 for all employees to set the respective conditional access policies.
As of March 2020, SkyKick products support MFA. Hope this helps.
It is my understanding they have a ticket in with Microsoft on this. The issue is related to PowerShell for Exchange with MFA, option 6 on your list you've attached, so I think I can get an exception until its resolved as every delegated admin partner is required to use Exchange PowerShell. I'll find out.
If you are using ExO Powershell against Customer tenants you can request an exception - and there is already a new solution you can adopt. See also https://www.cyberdrain.com/connect-to-exchange-online-automated-when-mfa-is-enabled-using-the-secureapp-model/
Not my work 🙂 - full kudos go to @KelvinTegelaar
No, this is not something you need to do every 90 days. You need to use the refreshtoken to get a new access token and thus you can get a new refreshtoken which has again 90 days lifetime.
@sansbacher has explained this quite good in his post here: https://www.microsoftpartnercommunity.com/t5/Secure-Application-Model/Exchange-Online-and-the-Secure-App-Model/m-p/15421/highlight/true#M125
And Kelvin has also integrated this in his script.
I do use unattended/headless scheduled Exchange Online PowerShell scripts against our client/customer tenants every day (and AzureAD/MSOnline PowerShell). The work Kelvin did allowed me to do that, and it works with MFA and the Secure App Model - so that may limit the ability to get an exception.
However Kelvin's script only does the INITIAL work of creating the Azure AD App, setting permissions, and returning the RefreshTokens, etc. It doesn't include anything about renewing the RefreshTokens every 90 days - you need to do that yourself. (you could re-run his script, but that would mean creating a new App and saving new Tokens, and is also a manual interactive process - it couldn't be automated).
Since the RefreshTokens expire every 90 days, but every time you use a RefreshToken (to get an AccessToken which is used to actually DO anything) you also get back a new RefreshToken (good for another 90 days).
What you need to do is:
- Run Kelvin's script to generate the Azure AD App, capture all the output, including the Username/UPN you used (the account with MFA that you used to provide Consent)
- Store the RefreshTokens somewhere other than your code - a text file, database, Azure Vault, PasswordState, etc. Anything you can read() or GET from your script. Hopefully somewhere secure! [The other values, the App ID and Secret, etc could be stored in the script, they won't need to be updated for a year - or you can also store these somewhere other than your script]
- Your ExO/MSOnline/AzureAD scripts need to read() the file or GET via a REST call, etc to retrieve the RefreshTokens (using them to get an AccessToken, and then connect to the MS services, as detailed in https://www.microsoftpartnercommunity.com/t5/Secure-Application-Model/Exchange-Online-and-the-Secure-App-Model/m-p/15421/highlight/true#M125
- At least every 90 days, I do it every week: have a different script that also reads() or GETs the RefreshToken, uses it to get an AccessToken but instead of using that, just needs the new RefreshToken that also comes back. Then write() or POST/PATCH that back to your file/vault/database. You need to do this for both RefreshTokens. Schedule that script to run unattended.
That way your main "worker" script (step 3) will always be reading/getting a RefreshToken that has is less than 90 days old, and doesn't have to care about the age of the RefreshToken*. Only the renew script (step 4) needs to read and white the RefreshToken, and by running every week you'll have lots of heads up if there's a problem.
*I should also add: the AccessToken you receive when you redeem the RefreshToken is only good for 60 mins - so no sense storing that! But... if you are running a very long process (eg: Get-Mailbox for thousands of mailboxes, then do something that takes a while for each Mailbox) that may take longer than 60 mins in total: then you will need to build into your main script a process to request a new AccessToken before the 60 min timer runs out.
EDIT to add: the Refresh Token renewal process works well for me, except right now an issue with renewing the Exch Online token, likely related to our MFA policies... I just posted about this in the Secure App section..
I hope that helps!