Microsoft Entra Conditional Access: Token protection (Preview)

Token protection (sometimes referred to as token binding in the industry) attempts to reduce attacks using token theft by ensuring a token is usable only from the intended device. When an attacker is able to steal a token, by hijacking or replay, they can impersonate their victim until the token expires or is revoked. Token theft is thought to be a relatively rare event, but the damage from it can be significant.

Token protection creates a cryptographically secure tie between the token and the device (client secret) it's issued to. Without the client secret, the bound token is useless. When a user registers a Windows 10 or newer device in Microsoft Entra ID, their primary identity is bound to the device. What this means: A policy can ensure that only bound sign-in session (or refresh) tokens, otherwise known as Primary Refresh Tokens (PRTs) are used by applications when requesting access to a resource.

Important

Token protection is currently in public preview. For more information about previews, see Universal License Terms For Online Services. With this preview, we're giving you the ability to create a Conditional Access policy to require token protection for sign-in tokens (refresh tokens) for specific services. We support token protection for sign-in tokens in Conditional Access for desktop applications accessing Exchange Online and SharePoint Online on Windows devices.

Important

The following changes have been made to Token Protection since the initial public preview release:

  • Sign In logs output: The value of the string used in enforcedSessionControls and sessionControlsNotSatisfied changed from Binding to SignInTokenProtection in late June 2023. Queries on Sign In Log data should be updated to reflect this change.

  • Devices that are joined to Microsoft Entra using certain methods are no longer supported. See the known limitations section for a complete list.

  • Error code change: The Token protection Conditional Access policy error code is changing from 53003 to 530084 to better identify errors related to token protection.

Screenshot of a Conditional Access policy requiring token protection as the session control.

Requirements

Using this feature requires Microsoft Entra ID P2 licenses. To find the right license for your requirements, see Compare generally available features of Microsoft Entra ID.

Note

Token protection enforcement is part of Microsoft Entra ID Protection and requires Microsoft Entra ID P2 licenses at general availability.

The following devices and applications support accessing resources on which a token protection Conditional Access policy is applied:

Supported devices:

  • Windows 10 or newer devices that are Microsoft Entra joined, Microsoft Entra hybrid joined, or Microsoft Entra registered. See the known limitations section for unsupported device types.
  • Windows Server 2019 or newer that are hybrid Microsoft Entra joined.

Supported applications:

  • OneDrive sync client version 22.217 or newer
  • Teams native client version 1.6.00.1331 or newer
  • Power BI desktop version 2.117.841.0 (May 2023) or newer
  • Exchange PowerShell module version 3.7.0 or newer
  • Microsoft Graph PowerShell version 2.0.0 or newer with EnableLoginByWAM option
  • Visual Studio 2022 or newer when using the 'Windows authentication broker' Sign-in option

Known limitations

  • Office perpetual clients aren't supported.
  • The following applications don't support signing in using protected token flows and users are blocked when accessing Exchange and SharePoint:
    • PowerShell modules accessing SharePoint
    • PowerQuery extension for Excel
    • Extensions to Visual Studio Code which access Exchange or SharePoint
  • The following Windows client devices aren't supported:
    • Surface Hub
    • Windows-based Microsoft Teams Rooms (MTR) systems
  • External users who meet the token protection device registration requirements in their home tenant are supported. However, users who don't meet these requirements see an unclear error message with no indication of the root cause.
  • Devices registered with Microsoft Entra ID using the following methods are unsupported:
  • New [Microsoft Entra registered devices](Microsoft Entra registered devices) on Windows versions before 24H2 might be blocked if users don't perform a fresh sign-in during registration. If blocked, users must re-register the device.

To identify the impacted devices due to unsupported registration types listed previously, inspect tokenProtectionStatusDetails attribute in the Sign-in logs. Token requests that are blocked due to an unsupported device registration type, can be identified with a signInSessionStatusCode value of 1003.

To prevent any disruption for new onboarding, you can modify the token protection Conditional Access policy by adding a device filter condition that excludes any devices that fall in the previously described deployment category. For example, to exclude:

  • Cloud PCs that are Microsoft Entra joined, you can use systemLabels -eq "CloudPC" and trustType -eq "AzureAD".
  • Azure Virtual Desktops that are Microsoft Entra joined, you can use systemLabels -eq "AzureVirtualDesktop" and trustType -eq "AzureAD".
  • Power Automate hosted machine groups that are Microsoft Entra joined, you can use systemLabels -eq "MicrosoftPowerAutomate" and trustType -eq "AzureAD".
  • Windows virtual machines in Azure that are Microsoft Entra joined, you can use systemLabels -eq "AzureResource" and trustType -eq "AzureAD".

Deployment

For users, the deployment of a Conditional Access policy to enforce token protection should be invisible when using compatible client platforms on registered devices and compatible applications.

To minimize the likelihood of user disruption due to app or device incompatibility, we highly recommend:

  • Start with a pilot group of users, and expand over time.
  • Create a Conditional Access policy in report-only mode before moving to enforcement of token protection.
  • Capture both Interactive and Non-interactive sign in logs.
  • Analyze these logs for long enough to cover normal application use.
  • Add known good users to an enforcement policy.

This process helps to assess your users’ client and app compatibility for token protection enforcement.

Create a Conditional Access policy

Users who perform specialized roles like those described in Privileged access security levels are possible targets for this functionality. We recommend piloting with a small subset to begin.

The steps that follow help create a Conditional Access policy to require token protection for Exchange Online and SharePoint Online on Windows devices.

  1. Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator.
  2. Browse to Protection > Conditional Access > Policies.
  3. Select New policy.
  4. Give your policy a name. We recommend that organizations create a meaningful standard for the names of their policies.
  5. Under Assignments, select Users or workload identities.
    1. Under Include, select the users or groups who are testing this policy.
    2. Under Exclude, select Users and groups and choose your organization's emergency access or break-glass accounts.
  6. Under Target resources > Resources (formerly cloud apps) > Include > Select resources
    1. Under Select, select the following applications supported by the preview:

      1. Office 365 Exchange Online
      2. Office 365 SharePoint Online

      Warning

      Your Conditional Access policy should only be configured for these applications. Selecting the Office 365 application group might result in unintended failures. This change is an exception to the general rule that the Office 365 application group should be selected in a Conditional Access policy.

    2. Choose Select.

  7. Under Conditions:
    1. Under Device platforms:
      1. Set Configure to Yes.
      2. Include > Select device platforms > Windows.
      3. Select Done.
    2. Under Client apps:
      1. Set Configure to Yes.

        Warning

        Not configuring the Client Apps condition, or leaving Browser selected might cause applications that use MSAL.js, such as Teams Web to be blocked.

      2. Under Modern authentication clients, only select Mobile apps and desktop clients. Leave other items unchecked.

      3. Select Done.

  8. Under Access controls > Session, select Require token protection for sign-in sessions and select Select.
  9. Confirm your settings and set Enable policy to Report-only.
  10. Select Create to create to enable your policy.

After administrators confirm the settings using report-only mode, they can move the Enable policy toggle from Report-only to On.

Tip

Since Conditional Access policies requiring token protection are currently only available for Windows devices, it's necessary to secure your environment against potential policy bypass when an attacker might appear to come from a different platform.

In addition, you should configure the following policies:

Capture logs and analyze

Monitor Conditional Access enforcement of token protection before and after enforcement using features like Policy impact (Preview), Sign-in logs, or Log Analytics.

Sign-in logs

Use Microsoft Entra sign-in log to verify the outcome of a token protection enforcement policy in report only mode or in enabled mode.

Screenshot showing an example of a policy not being satisfied.

  1. Sign in to the Microsoft Entra admin center as at least a Conditional Access Administrator.
  2. Browse to Identity > Monitoring & health > Sign-in logs.
  3. Select a specific request to determine if the policy is applied or not.
  4. Go to the Conditional Access or Report-Only pane depending on its state and select the name of your policy requiring token protection.
  5. Under Session Controls check to see if the policy requirements were satisfied or not.
  6. To find more details about the binding state of the request, select the pane Basic Info and see the field Token Protection - Sign In Session. Possible values are:
    1. Bound: the request was using bound protocols. Some sign-ins might include multiple requests, and all requests must be bound to satisfy the token protection policy. Even if an individual request appears to be bound, it doesn't ensure compliance with the policy if other requests are unbound. To see all requests for a sign-in, you can filter all requests for a specific user or look by corelationid.
    2. Unbound: the request wasn't using bound protocols. Possible statusCodes when request is unbound are:
      1. 1002: The request is unbound due to the lack of Microsoft Entra ID device state.
      2. 1003: The request is unbound because the Microsoft Entra ID device state doesn't satisfy Conditional Access policy requirements for token protection. This error could be due to an unsupported device registration type, or the device wasn't registered using fresh sign-in credentials.
      3. 1005: The request is unbound for other unspecified reasons.
      4. 1006: The request is unbound because the OS version is unsupported.
      5. 1008: The request is unbound because the client isn't integrated with the platform broker, such as Windows Account Manager (WAM).

Screenshot showing a sample sign-in with the Token Protection - Sign In Session attribute highlighted.

Log Analytics

You can also use Log Analytics to query the sign-in logs (interactive and non-interactive) for blocked requests due to token protection enforcement failure.

Here's a sample Log Analytics query searching the non-interactive sign-in logs for the last seven days, highlighting Blocked versus Allowed requests by Application. These queries are only samples and are subject to change.

Note

Sign In logs output: The value of the string used in "enforcedSessionControls" and "sessionControlsNotSatisfied" changed from "Binding" to "SignInTokenProtection" in late June 2023. Queries on Sign In Log data should be updated to reflect this change. The examples cover both values to include historical data.

//Per Apps query 
// Select the log you want to query (SigninLogs or AADNonInteractiveUserSignInLogs ) 
//SigninLogs 
AADNonInteractiveUserSignInLogs 
// Adjust the time range below 
| where TimeGenerated > ago(7d) 
| project Id,ConditionalAccessPolicies, Status,UserPrincipalName, AppDisplayName, ResourceDisplayName 
| where ConditionalAccessPolicies != "[]" 
| where ResourceDisplayName == "Office 365 Exchange Online" or ResourceDisplayName =="Office 365 SharePoint Online" 
//Add userPrinicpalName if you want to filter  
// | where UserPrincipalName =="<user_principal_Name>" 
| mv-expand todynamic(ConditionalAccessPolicies) 
| where ConditionalAccessPolicies ["enforcedSessionControls"] contains '["Binding"]' or ConditionalAccessPolicies ["enforcedSessionControls"] contains '["SignInTokenProtection"]' 
| where ConditionalAccessPolicies.result !="reportOnlyNotApplied" and ConditionalAccessPolicies.result !="notApplied" 
| extend SessionNotSatisfyResult = ConditionalAccessPolicies["sessionControlsNotSatisfied"] 
| extend Result = case (SessionNotSatisfyResult contains 'SignInTokenProtection' or SessionNotSatisfyResult contains 'SignInTokenProtection', 'Block','Allow')
| summarize by Id,UserPrincipalName, AppDisplayName, Result 
| summarize Requests = count(), Users = dcount(UserPrincipalName), Block = countif(Result == "Block"), Allow = countif(Result == "Allow"), BlockedUsers = dcountif(UserPrincipalName, Result == "Block") by AppDisplayName 
| extend PctAllowed = round(100.0 * Allow/(Allow+Block), 2) 
| sort by Requests desc 

The result of the previous query should be similar to the following screenshot:

Screenshot showing example results of a Log Analytics query looking for token protection policies

The following query example looks at the non-interactive sign-in log for the last seven days, highlighting Blocked versus Allowed requests by User.

//Per users query 
// Select the log you want to query (SigninLogs or AADNonInteractiveUserSignInLogs ) 
//SigninLogs 
AADNonInteractiveUserSignInLogs 
// Adjust the time range below 
| where TimeGenerated > ago(7d) 
| project Id,ConditionalAccessPolicies, UserPrincipalName, AppDisplayName, ResourceDisplayName 
| where ConditionalAccessPolicies != "[]" 
| where ResourceDisplayName == "Office 365 Exchange Online" or ResourceDisplayName =="Office 365 SharePoint Online" 
//Add userPrincipalName if you want to filter  
// | where UserPrincipalName =="<user_principal_Name>" 
| mv-expand todynamic(ConditionalAccessPolicies) 
| where ConditionalAccessPolicies ["enforcedSessionControls"] contains '["Binding"]' or ConditionalAccessPolicies ["enforcedSessionControls"] contains '["SignInTokenProtection"]'
| where ConditionalAccessPolicies.result !="reportOnlyNotApplied" and ConditionalAccessPolicies.result !="notApplied" 
| extend SessionNotSatisfyResult = ConditionalAccessPolicies.sessionControlsNotSatisfied 
| extend Result = case (SessionNotSatisfyResult contains 'SignInTokenProtection' or SessionNotSatisfyResult contains 'SignInTokenProtection', 'Block','Allow')
| summarize by Id, UserPrincipalName, AppDisplayName, ResourceDisplayName,Result  
| summarize Requests = count(),Block = countif(Result == "Block"), Allow = countif(Result == "Allow") by UserPrincipalName, AppDisplayName,ResourceDisplayName 
| extend PctAllowed = round(100.0 * Allow/(Allow+Block), 2) 
| sort by UserPrincipalName asc   

The following query example looks at the non-interactive sign-in log for the last seven days, highlighting users that are using devices, where Microsoft Entra ID device state doesn't satisfy Token protection CA policy requirements.

AADNonInteractiveUserSignInLogs 
// Adjust the time range below 
| where TimeGenerated > ago(7d) 
| where TokenProtectionStatusDetails!= "" 
| extend parsedBindingDetails = parse_json(TokenProtectionStatusDetails) 
| extend bindingStatus = tostring(parsedBindingDetails["signInSessionStatus"]) 
| extend bindingStatusCode = tostring(parsedBindingDetails["signInSessionStatusCode"]) 
| where bindingStatusCode == 1003 
| summarize count() by UserPrincipalName 

What is a Primary Refresh Token?