Entra ID Identity Protection Monitors Sign-Ins to Find Problem Accounts
Entra ID Identity Protection is a solution that uses machine learning to monitor and detect problematic sign-in activity for a tenant. The idea is that machine learning is better at examining audit logs to recognize signs of potential problems, especially when a tenant supports a large number of accounts. Entra ID Identity Protection requires Azure AD Premium P2 licenses.
Graph API for Entra ID Risky Users
The riskyUser resource type is a Graph API used by Entra ID Identity Protection to. programmatically represent risky user accounts. Usually, it is Entra ID Identity Protection that marks an account as being at risk based on the pattern of activity for the account (for instance, a large number of attempted sign-ins that fail). Alternatively, the risk state of a user can be set by an administrator if they know that an account is compromised.
The actions supported by the API are:
List risky users.
Get details of a risky user.
List the history of a risky user.
Confirm that the state of a user account is risky due to known compromise.
Dismiss the risky status for a user (use the Graph API as shown below).
Examples of Microsoft Graph PowerShell SDK cmdlets based on the Risky User API include:
# Use scope IdentityRiskyUser.ReadWrite.All to read risky user information and IdentityRiskyUser.ReadWrite.All to update.
Connect-MgGraph -Scopes IdentityRiskyUser.ReadWrite.All
Get-MgRiskyUser | Sort-Object RiskLastUpdatedDateTime -Descending
Get-MgRiskyUser -RiskyUserId 96bfb216-e88c-4f1f-86d7-04747e5fc686 | Format-List)
Get-MgRiskyUserHistory -RiskyUserId 96bfb216-e88c-4f1f-86d7-04747e5fc686 | Format-List)
Confirm-MgRiskyUserCompromised -UserIds (Get-MgUser -UserId Ben.James@Office365itpros.com).Id
Accounts that need to be checked show up under risky activities in the Protection section of the Entra ID admin center (risky activities can be attributed to service principals if Identity Protection finds an app doing something unusual). Figure 1 shows the details logged for an account after an administrator ran the Confirm-MgRiskyUserCompromised cmdlet. This action forces Identity Protection to regard the account as being highly at risk, so it sends global administrators email to inform them about the problem.
Figure 1: Details of a risky user in Entra ID Identity Protection
Once an account is flagged as risky, it remains in this state until an administrator remediates the risk. On my tenant, I had some old risky users that hadn’t been processed. To clean things up, I used the PowerShell code below to find risky users awaiting administrator remediation and checked the last updated date to see if the risky user state was more than 183 days old. If true, I used the Graph API to dismiss the risky user state.
Write-Host "Finding risky users"
[array]$RiskyUsers = Get-MgRiskyUser -Filter "(riskState ne 'remediated') and (riskState ne 'dismissed')" | Sort-Object RiskLastUpdatedDateTime -Descending
$Uri = "https://graph.microsoft.com/beta/riskyUsers/dismiss"
[datetime]$CheckDate = (Get-Date).AddDays(-183)
ForEach ($User in $RiskyUsers) {
If ($User.RiskLastUpdatedDateTime -le $CheckDate) {
Write-Host ("User {0} ({1}) risk state last updated on {2} - removing..." -f $User.UserDisplayName, $User.UserPrincipalName, $User.RiskLastUpdatedDateTime)
$DismissedUserInfo = '{"UserIds": [ "' + $User.Id + '" ]}'
Invoke-MgGraphRequest -Uri $Uri -Body $DismissedUserInfo -Method Post
}
}
User Jim.Smith (Jim.Smith@office365itpros.com) risk state last updated on 18/08/2022 15:54:04 - removing...
User Chris Bishop (Chris.Bishop@office365itpros.com) risk state last updated on 11/05/2021 06:05:39 - removing...
This code dismisses the risk state even if the state is deemed High. A more complete implementation might exclude these risky users and process only those with risk state of medium or low.
It takes a few minutes before the dismissed state becomes effective for accounts.
Linking Entra ID Risky Users to Conditional Access
When I first read about the Confirm-MgRiskyUserCompromised cmdlet, I wondered if I would ever use such a command. If an administrator knows about an account compromise, surely their first step is to prevent access to whoever has compromised the account by disabling access and changing its password? After all, no need exists to mark an account as risky when an administrator knows that it is compromised/
But then I wondered if the advantage lies in the fact that high-risk accounts can be picked up by a conditional access policy. Identity Protection started off with its own risk policies, and Microsoft is now encouraging customers to migrate to conditional access policies instead, citing advantages such as Graph API support and greater flexibility. Given the number of features Microsoft has added to conditional access policies recently, like protected actions and authentication strength, the argument is certainly true.
Creating an authentication policy to block access to accounts marked at risk is straightforward.
Select the users within scope of the policy.
Add All Cloud Apps as the target resource.
Set User Risk to High (or High and Medium).
Set session sign-in frequency to every time.
Under access control, select grant access with a password change (and for good measure, require multi-factor authentication).
When the conditional access policy is active, continuous access evaluation will detect the risk and block connections from any user (Figure 2) marked as High risk (like those marked by the Confirm-MgRiskyUserCompromised cmdlet). An administrator will have to reset the account password or, if the account is enabled for Self-Service Password Reset (SSPR), the user will have to choose a new password before they can sign in again.
Figure 2: Entra ID blocks a risky user from making a connection
The thing about conditional access policies is that it’s easy to get into a mess with conflicting and competing policies. I always test with a single user and I use the IdPowerTools app to document the set of policies defined in my tenant.
Entra ID Risky Users Just Another Thing to Consider in a Security Plan
Entra ID Identity Protection isn’t a silver bullet to prevent user account compromise. Enabling multi-factor authentication for all user accounts is a much more fundamental solution to the compromise problem. Identity Protection brings some extra intelligence to the task of managing sign-ins and helps administrators to identify problem connections more quickly and more accurately. Having a Graph API (and SDK cmdlets) available to automate operations for risky user accounts is a bonus.
Deciding how to use these tools takes time and consideration. They must fit in your overall security posture and not conflict with any of the other protection techniques that are in use. Identity Protection is just another factor for administrator to consider.
Learn how to exploit the data available to Microsoft 365 tenant administrators through the Office 365 for IT Pros eBook. We love figuring out how things work.
{"id":null,"mode":"button","open_style":"in_modal","currency_code":"EUR","currency_symbol":"\u20ac","currency_type":"decimal","blank_flag_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/blank.gif","flag_sprite_url":"https:\/\/office365itpros.com\/wp-content\/plugins\/tip-jar-wp\/\/assets\/images\/flags\/flags.png","default_amount":100,"top_media_type":"featured_image","featured_image_url":"https:\/\/office365itpros.com\/wp-content\/uploads\/2022\/11\/cover-141x200.jpg","featured_embed":"","header_media":null,"file_download_attachment_data":null,"recurring_options_enabled":true,"recurring_options":{"never":{"selected":true,"after_output":"One time only"},"weekly":{"selected":false,"after_output":"Every week"},"monthly":{"selected":false,"after_output":"Every month"},"yearly":{"selected":false,"after_output":"Every year"}},"strings":{"current_user_email":"","current_user_name":"","link_text":"Virtual Tip Jar","complete_payment_button_error_text":"Check info and try again","payment_verb":"Pay","payment_request_label":"Office 365 for IT Pros","form_has_an_error":"Please check and fix the errors above","general_server_error":"Something isn't working right at the moment. Please try again.","form_title":"Office 365 for IT Pros","form_subtitle":null,"currency_search_text":"Country or Currency here","other_payment_option":"Other payment option","manage_payments_button_text":"Manage your payments","thank_you_message":"Thank you for supporting the work of Office 365 for IT Pros!","payment_confirmation_title":"Office 365 for IT Pros","receipt_title":"Your Receipt","print_receipt":"Print Receipt","email_receipt":"Email Receipt","email_receipt_sending":"Sending receipt...","email_receipt_success":"Email receipt successfully sent","email_receipt_failed":"Email receipt failed to send. Please try again.","receipt_payee":"Paid to","receipt_statement_descriptor":"This will show up on your statement as","receipt_date":"Date","receipt_transaction_id":"Transaction ID","receipt_transaction_amount":"Amount","refund_payer":"Refund from","login":"Log in to manage your payments","manage_payments":"Manage Payments","transactions_title":"Your Transactions","transaction_title":"Transaction Receipt","transaction_period":"Plan Period","arrangements_title":"Your Plans","arrangement_title":"Manage Plan","arrangement_details":"Plan Details","arrangement_id_title":"Plan ID","arrangement_payment_method_title":"Payment Method","arrangement_amount_title":"Plan Amount","arrangement_renewal_title":"Next renewal date","arrangement_action_cancel":"Cancel Plan","arrangement_action_cant_cancel":"Cancelling is currently not available.","arrangement_action_cancel_double":"Are you sure you'd like to cancel?","arrangement_cancelling":"Cancelling Plan...","arrangement_cancelled":"Plan Cancelled","arrangement_failed_to_cancel":"Failed to cancel plan","back_to_plans":"\u2190 Back to Plans","update_payment_method_verb":"Update","sca_auth_description":"Your have a pending renewal payment which requires authorization.","sca_auth_verb":"Authorize renewal payment","sca_authing_verb":"Authorizing payment","sca_authed_verb":"Payment successfully authorized!","sca_auth_failed":"Unable to authorize! Please try again.","login_button_text":"Log in","login_form_has_an_error":"Please check and fix the errors above","uppercase_search":"Search","lowercase_search":"search","uppercase_page":"Page","lowercase_page":"page","uppercase_items":"Items","lowercase_items":"items","uppercase_per":"Per","lowercase_per":"per","uppercase_of":"Of","lowercase_of":"of","back":"Back to plans","zip_code_placeholder":"Zip\/Postal Code","download_file_button_text":"Download File","input_field_instructions":{"tip_amount":{"placeholder_text":"How much would you like to tip?","initial":{"instruction_type":"normal","instruction_message":"How much would you like to tip? Choose any currency."},"empty":{"instruction_type":"error","instruction_message":"How much would you like to tip? Choose any currency."},"invalid_curency":{"instruction_type":"error","instruction_message":"Please choose a valid currency."}},"recurring":{"placeholder_text":"Recurring","initial":{"instruction_type":"normal","instruction_message":"How often would you like to give this?"},"success":{"instruction_type":"success","instruction_message":"How often would you like to give this?"},"empty":{"instruction_type":"error","instruction_message":"How often would you like to give this?"}},"name":{"placeholder_text":"Name on Credit Card","initial":{"instruction_type":"normal","instruction_message":"Enter the name on your card."},"success":{"instruction_type":"success","instruction_message":"Enter the name on your card."},"empty":{"instruction_type":"error","instruction_message":"Please enter the name on your card."}},"privacy_policy":{"terms_title":"Terms and conditions","terms_body":null,"terms_show_text":"View Terms","terms_hide_text":"Hide Terms","initial":{"instruction_type":"normal","instruction_message":"I agree to the terms."},"unchecked":{"instruction_type":"error","instruction_message":"Please agree to the terms."},"checked":{"instruction_type":"success","instruction_message":"I agree to the terms."}},"email":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email address"},"success":{"instruction_type":"success","instruction_message":"Enter your email address"},"blank":{"instruction_type":"error","instruction_message":"Enter your email address"},"not_an_email_address":{"instruction_type":"error","instruction_message":"Make sure you have entered a valid email address"}},"note_with_tip":{"placeholder_text":"Your note here...","initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"empty":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"not_empty_initial":{"instruction_type":"normal","instruction_message":"Attach a note to your tip (optional)"},"saving":{"instruction_type":"normal","instruction_message":"Saving note..."},"success":{"instruction_type":"success","instruction_message":"Note successfully saved!"},"error":{"instruction_type":"error","instruction_message":"Unable to save note note at this time. Please try again."}},"email_for_login_code":{"placeholder_text":"Your email address","initial":{"instruction_type":"normal","instruction_message":"Enter your email to log in."},"success":{"instruction_type":"success","instruction_message":"Enter your email to log in."},"blank":{"instruction_type":"error","instruction_message":"Enter your email to log in."},"empty":{"instruction_type":"error","instruction_message":"Enter your email to log in."}},"login_code":{"initial":{"instruction_type":"normal","instruction_message":"Check your email and enter the login code."},"success":{"instruction_type":"success","instruction_message":"Check your email and enter the login code."},"blank":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."},"empty":{"instruction_type":"error","instruction_message":"Check your email and enter the login code."}},"stripe_all_in_one":{"initial":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"empty":{"instruction_type":"error","instruction_message":"Enter your credit card details here."},"success":{"instruction_type":"normal","instruction_message":"Enter your credit card details here."},"invalid_number":{"instruction_type":"error","instruction_message":"The card number is not a valid credit card number."},"invalid_expiry_month":{"instruction_type":"error","instruction_message":"The card's expiration month is invalid."},"invalid_expiry_year":{"instruction_type":"error","instruction_message":"The card's expiration year is invalid."},"invalid_cvc":{"instruction_type":"error","instruction_message":"The card's security code is invalid."},"incorrect_number":{"instruction_type":"error","instruction_message":"The card number is incorrect."},"incomplete_number":{"instruction_type":"error","instruction_message":"The card number is incomplete."},"incomplete_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incomplete."},"incomplete_expiry":{"instruction_type":"error","instruction_message":"The card's expiration date is incomplete."},"incomplete_zip":{"instruction_type":"error","instruction_message":"The card's zip code is incomplete."},"expired_card":{"instruction_type":"error","instruction_message":"The card has expired."},"incorrect_cvc":{"instruction_type":"error","instruction_message":"The card's security code is incorrect."},"incorrect_zip":{"instruction_type":"error","instruction_message":"The card's zip code failed validation."},"invalid_expiry_year_past":{"instruction_type":"error","instruction_message":"The card's expiration year is in the past"},"card_declined":{"instruction_type":"error","instruction_message":"The card was declined."},"missing":{"instruction_type":"error","instruction_message":"There is no card on a customer that is being charged."},"processing_error":{"instruction_type":"error","instruction_message":"An error occurred while processing the card."},"invalid_request_error":{"instruction_type":"error","instruction_message":"Unable to process this payment, please try again or use alternative method."},"invalid_sofort_country":{"instruction_type":"error","instruction_message":"The billing country is not accepted by SOFORT. Please try another country."}}}},"fetched_oembed_html":false}