Azure Active Directory (Azure AD) serves as Microsoft's cloud-based service for identity and access management. It is instrumental in enabling employees to sign in and gain access to resources, both within and beyond the organization, encompassing Microsoft 365, the Azure portal, and a multitude of other SaaS applications. The design of Azure AD focuses on delivering essential identity services, prominently including authentication, authorization, and user management.
Key features of Azure AD involve multi-factor authentication and conditional access, alongside seamless integration with other Microsoft security services. These features significantly elevate the security of user identities and empower organizations to effectively implement and enforce their access policies. As a fundamental component of Microsoft's cloud services ecosystem, Azure AD is pivotal for the cloud-based management of user identities.
Entities
Connection
azlogin#This will open the browser (if not use --use-device-code)azlogin-u<username>-p<password>#Specify user and passwordazlogin--identity#Use the current machine managed identity (metadata)az login --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID #Login with user managed identity
# Login as service principal## With passwordaz login --service-principal -u <application ID> -p VerySecret --tenant contoso.onmicrosoft.com # Tenant can also be the tenant UUID
## With certazlogin--service-principal-u<applicationID>-p~/mycertfile.pem--tenantcontoso.onmicrosoft.com# Request access token (ARM)azaccountget-access-token# Request access token for different resource. Supported tokens: aad-graph, arm, batch, data-lake, media, ms-graph, oss-rdbms
azaccountget-access-token--resource-typeaad-graph# If you want to configure some defaultsazconfigure# Get user logged-in alreadyazadsigned-in-usershow# Helpazfind"vm"# Find vm commandsazvm-h# Get subdomainsazaduserlist--query-examples# Get examples
# Login Open browserConnect-MgGraph# Login with service principal secret## App ID and Tenant ID of your Azure AD App Registration$appId ="<appId>"$tenantId ="<tenantId>"$clientSecret ="<clientSecret>"## Convert the client secret to a SecureString$secureSecret =ConvertTo-SecureString-String $clientSecret -AsPlainText -Force## Create a PSCredential object$credential =New-Object System.Management.Automation.PSCredential ($appId, $secureSecret)## Connect using client credentialsConnect-MgGraph-TenantId $tenantId -ClientSecretCredential $credential# Login with token$token = (az account get-access-token --resource https://graph.microsoft.com--query accessToken -o tsv)$secureToken =ConvertTo-SecureString $token -AsPlainText -ForceConnect-MgGraph-AccessToken $secureToken# Find commandsFind-MgGraphCommand-command *Mg*
Connect-AzAccount#Open browser# Using credentials$passwd =ConvertTo-SecureString"Welcome2022!"-AsPlainText -Force$creds =New-Object System.Management.Automation.PSCredential("test@corp.onmicrosoft.com", $passwd)Connect-AzAccount-Credential $creds# Get Access Token(Get-AzAccessToken).Token# Request access token to other endpoints: AadGraph, AnalysisServices, Arm, Attestation, Batch, DataLake, KeyVault, MSGraph, OperationalInsights, ResourceManager, Storage, Synapse
(Get-AzAccessToken-ResourceTypeName MSGraph).Token(Get-AzAccessToken-Resource "https://graph.microsoft.com").Token# Connect with access tokenConnect-AzAccount-AccountId test@corp.onmicrosoft.com -AccessToken $tokenConnect-AzAccount-AccessToken $token -GraphAccessToken $graphaccesstoken -AccountId <ACCOUNT-ID>## The -AccessToken is from management.azure.com# Connect with Service principal/enterprise app secret$password =ConvertTo-SecureString'KWEFNOIRFIPMWL.--DWPNVFI._EDWWEF_ADF~SODNFBWRBIF'-AsPlainText -Force$creds =New-Object System.Management.Automation.PSCredential('2923847f-fca2-a420-df10-a01928bec653', $password)Connect-AzAccount-ServicePrincipal -Credential $creds -Tenant 29sd87e56-a192-a934-bca3-0398471ab4e7d#All the Azure AD cmdlets have the format *-AzAD*Get-Command*azad*#Cmdlets for other Azure resources have the format *Az*Get-Command*az*
#Using management$Token ='eyJ0eXAi..'# List subscriptions$URI ='https://management.azure.com/subscriptions?api-version=2020-01-01'$RequestParams =@{ Method ='GET' Uri = $URI Headers =@{'Authorization'="Bearer $Token" }}(Invoke-RestMethod @RequestParams).value# Using graphInvoke-WebRequest -Uri "https://graph.windows.net/myorganization/users?api-version=1.6" -Headers @{Authorization="Bearer {0}" -f $Token}
# Request tokens to access endpoints# ARMcurl"$IDENTITY_ENDPOINT?resource=https://management.azure.com&api-version=2017-09-01"-Hsecret:$IDENTITY_HEADER# Vaultcurl"$IDENTITY_ENDPOINT?resource=https://vault.azure.net&api-version=2017-09-01"-Hsecret:$IDENTITY_HEADER
Connect-AzureAD#Open browser# Using credentials$passwd =ConvertTo-SecureString"Welcome2022!"-AsPlainText -Force$creds =New-Object System.Management.Automation.PSCredential ("test@corp.onmicrosoft.com", $passwd)Connect-AzureAD-Credential $creds# Using tokens## AzureAD cannot request tokens, but can use AADGraph and MSGraph tokens to connectConnect-AzureAD-AccountId test@corp.onmicrosoft.com -AadAccessToken $token
When you login via CLI into Azure with any program, you are using an Azure Application from a tenant that belongs to Microsoft. These Applications, like the ones you can create in your account, have a client id. You won't be able to see all of them in the allowed applications lists you can see in the console, but they are allowed by default.
For example a powershell script that authenticates use an app with client id 1950a258-227b-4e31-a9cf-717495945fc2. Even if the app doesn't appear in the console, a sysadmin could block that application so users cannot access using tools that connects via that App.
However, there are other client-ids of applications that will allow you to connect to Azure:
# The important part is the ClientId, which identifies the application to login inside Azure$token =Invoke-Authorize-Credential $credential `-ClientId '1dfb5f98-f363-4b0f-b63a-8d20ada1e62d'`-Scope 'Files.Read.All openid profile Sites.Read.All User.Read email'`-Redirect_Uri "https://graphtryit-staging.azurewebsites.net/"`-Verbose -Debug `-InformationAction Continue$token =Invoke-Authorize-Credential $credential `-ClientId '65611c08-af8c-46fc-ad20-1888eb1b70d9'`-Scope 'openid profile Sites.Read.All User.Read email'`-Redirect_Uri "chrome-extension://imjekgehfljppdblckcmjggcoboemlah"`-Verbose -Debug `-InformationAction Continue$token =Invoke-Authorize-Credential $credential `-ClientId 'd3ce4cf8-6810-442d-b42e-375e14710095'`-Scope 'openid'`-Redirect_Uri "https://graphexplorer.azurewebsites.net/"`-Verbose -Debug `-InformationAction Continue
# Enumerate usersazaduserlist--outputtableazaduserlist--query"[].userPrincipalName"# Get info of 1 userazadusershow--id"test@corp.onmicrosoft.com"# Search "admin" usersazaduserlist--query"[].displayName"|findstr/i"admin"azaduserlist--query"[?contains(displayName,'admin')].displayName"# Search attributes containing the word "password"azaduserlist|findstr/i"password"|findstr/v"null,"# All users from Entra IDazaduserlist--query"[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi==null]"azaduserlist--query"[?onPremisesSecurityIdentifier==null].displayName"# All users synced from on-premazaduserlist--query"[].{osi:onPremisesSecurityIdentifier,upn:userPrincipalName}[?osi!=null]"azaduserlist--query"[?onPremisesSecurityIdentifier!=null].displayName"# Get groups where the user is a memberazaduserget-member-groups--id<email># Get roles assigned to the user in Azure (NOT in Entra ID)azroleassignmentlist--include-inherited--include-groups--include-classic-administratorstrue--assignee<email># Get ALL roles assigned in Azure in the current subscription (NOT in Entra ID)azroleassignmentlist--include-inherited--include-groups--include-classic-administratorstrue--all# Get EntraID roles assigned to a user## Get Tokenexport TOKEN=$(azaccountget-access-token--resourcehttps://graph.microsoft.com/--queryaccessToken-otsv)## Get userscurl-XGET"https://graph.microsoft.com/v1.0/users" \-H"Authorization: Bearer $TOKEN" \ -H"Content-Type: application/json"|jq## Get EntraID roles assigned to an usercurl -X GET "https://graph.microsoft.com/beta/rolemanagement/directory/transitiveRoleAssignments?\$count=true&\$filter=principalId%20eq%20'86b10631-ff01-4e73-a031-29e505565caa'" \
-H"Authorization: Bearer $TOKEN" \-H "ConsistencyLevel: eventual" \-H "Content-Type: application/json"|jq## Get role detailscurl -X GET "https://graph.microsoft.com/beta/roleManagement/directory/roleDefinitions/cf1c38e5-3621-4004-a7cb-879624dced7c" \
-H"Authorization: Bearer $TOKEN" \-H "Content-Type: application/json"|jq
# Enumerate UsersGet-AzureADUser-All $trueGet-AzureADUser-All $true| select UserPrincipalName# Get info of 1 userGet-AzureADUser-ObjectId test@corp.onmicrosoft.com | fl# Search "admin" usersGet-AzureADUser-SearchString "admin"#Search admin at the begining of DisplayName or userPrincipalNameGet-AzureADUser-All $true|?{$_.Displayname-match"admin"} #Search "admin" word in DisplayName# Get all attributes of a userGet-AzureADUser-ObjectId test@defcorphq.onmicrosoft.com|%{$_.PSObject.Properties.Name}# Search attributes containing the word "password"Get-AzureADUser -All $true |%{$Properties = $_;$Properties.PSObject.Properties.Name | % {if ($Properties.$_ -match 'password') {"$($Properties.UserPrincipalName) - $_ - $($Properties.$_)"}}}
# All users from AzureAD# All users from AzureADGet-AzureADUser-All $true|?{$_.OnPremisesSecurityIdentifier-eq$null}# All users synced from on-premGet-AzureADUser-All $true|?{$_.OnPremisesSecurityIdentifier-ne$null}# Objects created by a/any userGet-AzureADUser [-ObjectId<email>] |Get-AzureADUserCreatedObject# Devices owned by a userGet-AzureADUserOwnedDevice-ObjectId test@corp.onmicrosoft.com# Objects owned by a specific userGet-AzureADUserOwnedObject-ObjectId test@corp.onmicrosoft.com# Get groups & roles where the user is a memberGet-AzureADUserMembership-ObjectId 'test@corp.onmicrosoft.com'# Get devices owned by a userGet-AzureADUserOwnedDevice-ObjectId test@corp.onmicrosoft.com# Get devices registered by a userGet-AzureADUserRegisteredDevice-ObjectId test@defcorphq.onmicrosoft.com# Apps where a user has a role (role not shown)Get-AzureADUser-ObjectId roygcain@defcorphq.onmicrosoft.com |Get-AzureADUserAppRoleAssignment| fl *# Get Administrative Units of a user$userObj =Get-AzureADUser-Filter "UserPrincipalName eq 'bill@example.com'"Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where { $_.Id -eq $userObj.ObjectId } }
# Enumerate usersGet-AzADUser# Get details of a userGet-AzADUser-UserPrincipalName test@defcorphq.onmicrosoft.com# Search user by stringGet-AzADUser-SearchString "admin"#Search at the beginnig of DisplayNameGet-AzADUser|?{$_.Displayname-match"admin"}# Get roles assigned to a userGet-AzRoleAssignment-SignInName test@corp.onmicrosoft.com
It's highly recommended to add MFA to every user, however, some companies won't set it or might set it with a Conditional Access: The user will be required MFA if it logs in from an specific location, browser or some condition. These policies, if not configured correctly might be prone to bypasses. Check:
# Enumerate groupsaz ad group listaz ad group list --query "[].[displayName]"-o table# Get info of 1 groupaz ad group show --group <group># Get "admin" groupsaz ad group list --query "[].displayName"| findstr /i "admin"az ad group list --query "[?contains(displayName,'admin')].displayName"# All groups from Entra IDaz ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi==null]"
az ad group list --query "[?onPremisesSecurityIdentifier==null].displayName"# All groups synced from on-premaz ad group list --query "[].{osi:onPremisesSecurityIdentifier,displayName:displayName,description:description}[?osi!=null]"
az ad group list --query "[?onPremisesSecurityIdentifier!=null].displayName"# Get members of groupaz ad group member list --group <group>--query "[].userPrincipalName"-o table# Check if member of groupaz ad group member check --group "VM Admins"--member-id <id># Get which groups a group is member ofaz ad group get-member-groups -g "VM Admins"# Get roles assigned to the group in Azure (NOT in Entra ID)az role assignment list --include-groups --include-classic-administrators true --assignee <group-id># To get Entra ID roles assigned check how it's done with users and use a group ID
# Enumerate GroupsGet-AzureADGroup-All $true# Get info of 1 groupGet-AzADGroup-DisplayName <resource_group_name>| fl# Get "admin" groupsGet-AzureADGroup-SearchString "admin"| fl #Groups starting by "admin"Get-AzureADGroup-All $true|?{$_.Displayname-match"admin"} #Groups with the word "admin"# Get groups allowing dynamic membershipGet-AzureADMSGroup|?{$_.GroupTypes-eq'DynamicMembership'}# All groups that are from Azure AD Get-AzureADGroup-All $true|?{$_.OnPremisesSecurityIdentifier-eq$null}# All groups that are synced from on-prem (note that security groups are not synced)Get-AzureADGroup-All $true|?{$_.OnPremisesSecurityIdentifier-ne$null}# Get members of a groupGet-AzureADGroupMember-ObjectId <group_id># Get roles of groupGet-AzureADMSGroup-SearchString "Contoso_Helpdesk_Administrators"#Get group idGet-AzureADMSRoleAssignment-Filter "principalId eq '69584002-b4d1-4055-9c94-320542efd653'"# Get Administrative Units of a group$groupObj =Get-AzureADGroup-Filter "displayname eq 'TestGroup'"Get-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -Id $_.Id | where {$_.Id -eq $groupObj.ObjectId} }
# Get Apps where a group has a role (role not shown)Get-AzureADGroup-ObjectId <id>|Get-AzureADGroupAppRoleAssignment| fl *
# Get all groupsGet-AzADGroup# Get details of a groupGet-AzADGroup-ObjectId <id># Search group by stringGet-AzADGroup-SearchString "admin"| fl *#Search at the beginnig of DisplayNameGet-AzADGroup|?{$_.Displayname-match"admin"}# Get members of groupGet-AzADGroupMember-GroupDisplayName <resource_group_name># Get roles of groupGet-AzRoleAssignment-ResourceGroupName <resource_group_name>
Add user to group
Owners of the group can add new users to the group
Groups can be dynamic, which basically means that if a user fulfil certain conditions it will be added to a group. Of course, if the conditions are based in attributes a user can control, he could abuse this feature to get inside other groups.
Check how to abuse dynamic groups in the following page:
# Get Service Principalsazadsplist--allazadsplist--all--query"[].[displayName,appId]"-otable# Get details of one SPazadspshow--id00000000-0000-0000-0000-000000000000# Search SP by stringazadsplist--all--query"[?contains(displayName,'app')].displayName"# Get owner of service principalazadspownerlist--id<id>--query"[].[displayName]"-otable# Get service principals owned by the current userazadsplist--show-mine# Get SPs with generated secret or certificateaz ad sp list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
# Get Service PrincipalsGet-AzureADServicePrincipal-All $true# Get details about a SPGet-AzureADServicePrincipal-ObjectId <id>| fl *# Get SP by string name or IdGet-AzureADServicePrincipal-All $true|?{$_.DisplayName-match"app"} | flGet-AzureADServicePrincipal-All $true|?{$_.AppId-match"103947652-1234-5834-103846517389"}# Get owner of SPGet-AzureADServicePrincipal-ObjectId <id>|Get-AzureADServicePrincipalOwner|fl *# Get objects owned by a SPGet-AzureADServicePrincipal-ObjectId <id>|Get-AzureADServicePrincipalOwnedObject# Get objects created by a SPGet-AzureADServicePrincipal-ObjectId <id>|Get-AzureADServicePrincipalCreatedObject# Get groups where the SP is a memberGet-AzureADServicePrincipal|Get-AzureADServicePrincipalMembershipGet-AzureADServicePrincipal-ObjectId <id>|Get-AzureADServicePrincipalMembership|fl *
# Get SPsGet-AzADServicePrincipal# Get info of 1 SPGet-AzADServicePrincipal-ObjectId <id># Search SP by stringGet-AzADServicePrincipal|?{$_.DisplayName-match"app"}# Get roles of a SPGet-AzRoleAssignment-ServicePrincipalName <String>
When an App is generated 2 types of permissions are given:
Permissions given to the Service Principal
Permissions the app can have and use on behalf of the user.
# List Appsazadapplistazadapplist--query"[].[displayName,appId]"-otable# Get info of 1 Appazadappshow--id00000000-0000-0000-0000-000000000000# Search App by stringazadapplist--query"[?contains(displayName,'app')].displayName"# Get the owner of an applicationazadappownerlist--id<id>--query"[].[displayName]"-otable# Get SPs owned by current userazadapplist--show-mine# Get apps with generated secret or certificateaz ad app list --query '[?length(keyCredentials) > `0` || length(passwordCredentials) > `0`].[displayName, appId, keyCredentials, passwordCredentials]' -o json
# List all registered applicationsGet-AzureADApplication-All $true# Get details of an applicationGet-AzureADApplication-ObjectId <id>| fl *# List all the apps with an application passwordGet-AzureADApplication-All $true|%{if(Get-AzureADApplicationPasswordCredential-ObjectID $_.ObjectID){$_}}# Get owner of an applicationGet-AzureADApplication-ObjectId <id>|Get-AzureADApplicationOwner|fl *
# Get AppsGet-AzADApplication# Get details of one AppGet-AzADApplication-ObjectId <id># Get App searching by stringGet-AzADApplication|?{$_.DisplayName-match"app"}# Get Apps with passwordGet-AzADAppCredential
An app with the permission AppRoleAssignment.ReadWrite can escalate to Global Admin by grating itself the role.
For more information check this.
A secret string that the application uses to prove its identity when requesting a token is the application password.
So, if find this password you can access as the service principalinside the tenant.
Note that this password is only visible when generated (you could change it but you cannot get it again).
The owner of the application can add a password to it (so he can impersonate it).
Logins as these service principals are not marked as risky and they won't have MFA.
# Get rolesazroledefinitionlist# Get assigned rolesazroleassignmentlist--all--query"[].roleDefinitionName"azroleassignmentlist--all|jq'.[] | .roleDefinitionName,.scope'# Get info of 1 roleazroledefinitionlist--name"AzureML Registry User"# Get only custom rolesazroledefinitionlist--custom-role-only# Get only roles assigned to the resource group indicatedazroledefinitionlist--resource-group<resource_group># Get only roles assigned to the indicated scopeazroledefinitionlist--scope<scope># Get all the principals a role is assigned toaz role assignment list --all --query "[].{principalName:principalName,principalType:principalType,resourceGroup:resourceGroup,roleDefinitionName:roleDefinitionName}[?roleDefinitionName=='<ROLE_NAME>']"
# Get all available role templatesGet-AzureADDirectoryroleTemplate# Get enabled roles (Assigned roles)Get-AzureADDirectoryRoleGet-AzureADDirectoryRole-ObjectId <roleID>#Get info about the role# Get custom roles - use AzureAdPreviewGet-AzureADMSRoleDefinition|?{$_.IsBuiltin-eq$False} | select DisplayName# Users assigned a role (Global Administrator)Get-AzureADDirectoryRole-Filter "DisplayName eq 'Global Administrator'"|Get-AzureADDirectoryRoleMemberGet-AzureADDirectoryRole-ObjectId <id>| fl# Roles of the Administrative Unit (who has permissions over the administrative unit and its members)Get-AzureADMSScopedRoleMembership-Id <id>| fl *
# Get role assignments on the subscriptionGet-AzRoleDefinition# Get Role definitionGet-AzRoleDefinition-Name "Virtual Machine Command Executor"# Get roles of a user or resourceGet-AzRoleAssignment-SignInName test@corp.onmicrosoft.comGet-AzRoleAssignment -Scope /subscriptions/<subscription-id>/resourceGroups/<res_group_name>/providers/Microsoft.Compute/virtualMachines/<vm_name>
# Get permissions over a resource using ARM directly$Token = (Get-AzAccessToken).Token$URI = 'https://management.azure.com/subscriptions/b413826f-108d-4049-8c11-d52d5d388768/resourceGroups/Research/providers/Microsoft.Compute/virtualMachines/infradminsrv/providers/Microsoft.Authorization/permissions?api-version=2015-07-01'
$RequestParams =@{ Method ='GET' Uri = $URI Headers =@{'Authorization'="Bearer $Token" }}(Invoke-RestMethod @RequestParams).value
Devices
# If you know how to do this send a PR!
# Enumerate DevicesGet-AzureADDevice-All $true| fl *# List all the active devices (and not the stale devices)Get-AzureADDevice-All $true|?{$_.ApproximateLastLogonTimeStamp-ne$null}# Get owners of all devicesGet-AzureADDevice-All $true|Get-AzureADDeviceRegisteredOwnerGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredOwner -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}
# Registred users of all the devicesGet-AzureADDevice-All $true|Get-AzureADDeviceRegisteredUserGet-AzureADDevice -All $true | %{if($user=Get-AzureADDeviceRegisteredUser -ObjectId $_.ObjectID){$_;$user.UserPrincipalName;"`n"}}
# Get dives managed using IntuneGet-AzureADDevice-All $true|?{$_.IsCompliant-eq"True"}# Get devices owned by a userGet-AzureADUserOwnedDevice-ObjectId test@corp.onmicrosoft.com# Get Administrative Units of a deviceGet-AzureADMSAdministrativeUnit | where { Get-AzureADMSAdministrativeUnitMember -ObjectId $_.ObjectId | where {$_.ObjectId -eq $deviceObjId} }
If a device (VM) is AzureAD joined, users from AzureAD are going to be able to login.
Moreover, if the logged user is Owner of the device, he is going to be local admin.
Administrative Units
For more information about administrative units check:
# List all administrative unitsazrest--methodGET--uri"https://graph.microsoft.com/v1.0/directory/administrativeUnits"# Get AU infoaz rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53"
# Get membersaz rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/members"
# Get principals with roles over the AUaz rest --method GET --uri "https://graph.microsoft.com/v1.0/directory/administrativeUnits/a76fd255-3e5e-405b-811b-da85c715ff53/scopedRoleMembers"
# Get Administrative UnitsGet-AzureADMSAdministrativeUnitGet-AzureADMSAdministrativeUnit-Id <id># Get ID of admin unit by string$adminUnitObj =Get-AzureADMSAdministrativeUnit-Filter "displayname eq 'Test administrative unit 2'"# List the users, groups, and devices affected by the administrative unitGet-AzureADMSAdministrativeUnitMember-Id <id># Get the roles users have over the members of the AUGet-AzureADMSScopedRoleMembership-Id <id>| fl #Get role ID and role members
Azure AD Identity Protection (AIP)
Azure AD Identity Protection (AIP) is a security service that uses automated detection and remediation to help protect user identities in Azure Active Directory from being compromised. AIP continuously monitors and assesses the risk of user sign-ins and identity configurations, automatically applying appropriate security measures, such as requiring multi-factor authentication or blocking potentially dangerous activities. This helps organizations prevent identity-based security breaches.
Flow:
Azure AD Identity Protection monitors user activities and collects data on user sign-ins, authentication events, and other relevant activities.
The service uses machine learning algorithms to analyze this data and detect potential security threats.
Azure AD Identity Protection assigns a level of risk to the threat (e.g. sign-in) and generate an alert if needed to perform some automatic action.
Azure AD Password Protection (APP)
Azure AD Password Protection (APP) is a security feature that helps prevent weak passwords in Azure Active Directory by enforcing strong password policies. APP blocks commonly used weak passwords and their variants, reducing the risk of password-related breaches. It can be applied both at the cloud level and on-premises Active Directory, enhancing overall password security across the organization.