Skip to content

Commit 39383f0

Browse files
authored
Merge pull request #227645 from MicrosoftGuyJFlo/TokenBindingPreview
[Azure AD] Conditional Access - Token Binding Preview
2 parents e656d33 + 73373b1 commit 39383f0

File tree

6 files changed

+179
-0
lines changed

6 files changed

+179
-0
lines changed

articles/active-directory/conditional-access/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
href: service-dependencies.md
4040
- name: Filter for applications
4141
href: concept-filter-for-applications.md
42+
- name: Token protection
43+
href: concept-token-protection.md
4244
- name: Location conditions
4345
href: location-condition.md
4446
- name: Workload identities
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: Token protection in Azure AD Conditional Access
3+
description: Learn how to use token protection in Conditional Access policies.
4+
ms.service: active-directory
5+
ms.subservice: conditional-access
6+
ms.topic: conceptual
7+
ms.date: 03/09/2023
8+
9+
ms.author: joflore
10+
author: MicrosoftGuyJFlo
11+
manager: amycolannino
12+
ms.reviewer: paulgarn
13+
14+
ms.collection: M365-identity-device-management
15+
---
16+
# Conditional Access: Token protection (preview)
17+
18+
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.
19+
20+
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 Azure AD, their primary identity is [bound to the device](../devices/concept-primary-refresh-token.md#how-is-the-prt-protected). This connection means that any issued sign-in token is tied to the device significantly reducing the chance of theft and replay attacks. These sign-in tokens are specifically the session cookies in Microsoft Edge and most Microsoft product refresh tokens in this preview release.
21+
22+
With this preview, we're giving you the ability to create a Conditional Access policy to require token protection for sign-in tokens for specific services. We support token protection for sign-in tokens in Conditional Access for Exchange Online and SharePoint Online on Windows devices.
23+
24+
:::image type="content" source="media/concept-token-protection/complete-policy-components-session.png" alt-text="Screenshot showing a Conditional Access policy requiring token protection as the session control":::
25+
26+
## Requirements
27+
28+
This preview supports the following configurations:
29+
30+
* Windows 10 or newer devices that are Azure AD joined, hybrid Azure AD joined, or Azure AD registered.
31+
* OneDrive sync client version 22.217 or later
32+
* Teams native client version 1.6.00.1331 or later
33+
* Office Perpetual clients aren't supported
34+
35+
### Known limitations
36+
37+
- External users (Azure AD B2B) aren't supported and shouldn't be included in your Conditional Access policy.
38+
- The following applications don't support signing in using protected token flows and users are blocked when accessing Exchange and SharePoint:
39+
- Power BI Desktop client
40+
- PowerShell modules accessing Exchange, SharePoint, or Microsoft Graph scopes that are served by Exchange or SharePoint
41+
- PowerQuery extension for Excel
42+
- Extensions to Visual Studio Code which access Exchange or SharePoint
43+
- Visual Studio
44+
- The following Windows client devices aren't supported:
45+
- Windows Server
46+
- Surface Hub
47+
48+
## Deployment
49+
50+
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.
51+
52+
To minimize the likelihood of user disruption due to app or device incompatibility, we highly recommend:
53+
54+
- Start with a pilot group of users, and expand over time.
55+
- Create a Conditional Access policy in [report-only mode](concept-conditional-access-report-only.md) before moving to enforcement of token protection.
56+
- Capture both Interactive and Non-interactive sign in logs.
57+
- Analyze these logs for long enough to cover normal application use.
58+
- Add known good users to an enforcement policy.
59+
60+
This process helps to assess your users’ client and app compatibility for token protection enforcement.
61+
62+
### Create a Conditional Access policy
63+
64+
Users who perform specialized roles like those described in [Privileged access security levels](/security/compass/privileged-access-security-levels#specialized) are possible targets for this functionality. We recommend piloting with a small subset to begin.
65+
66+
:::image type="content" source="media/concept-token-protection/exposed-policy-attributes.png" alt-text="Screenshot of a configured Conditional Access policy and its components." lightbox="media/concept-token-protection/exposed-policy-attributes.png":::
67+
68+
The steps that follow help create a Conditional Access policy to require token protection for Exchange Online and SharePoint Online on Windows devices.
69+
70+
1. Sign in to the **Azure portal** as a Conditional Access Administrator, Security Administrator, or Global Administrator.
71+
1. Browse to **Azure Active Directory** > **Security** > **Conditional Access**.
72+
1. Select **New policy**.
73+
1. Give your policy a name. We recommend that organizations create a meaningful standard for the names of their policies.
74+
1. Under **Assignments**, select **Users or workload identities**.
75+
1. Under **Include**, select the users or groups who are testing this policy.
76+
1. Under **Exclude**, select **Users and groups** and choose your organization's emergency access or break-glass accounts.
77+
1. Under **Cloud apps or actions** > **Include**, select **Select apps**.
78+
1. Under **Select**, select the following applications supported by the preview:
79+
1. Office 365 Exchange Online
80+
1. Office 365 SharePoint Online
81+
82+
> [!WARNING]
83+
> Your Conditional Access policy should only be configured for these applications. Selecting the **Office 365** application group may result in unintended failures. This is an exception to the general rule that the **Office 365** application group should be selected in a Conditional Access policy.
84+
85+
1. Choose **Select**.
86+
1. Under **Conditions**:
87+
1. Under **Device platforms**:
88+
1. Set **Configure** to **Yes**.
89+
1. **Include** > **Select device platforms** > **Windows**.
90+
1. Select **Done**.
91+
1. Under **Client apps**:
92+
1. Set **Configure** to **Yes**.
93+
1. Under Modern authentication clients, only select **Mobile apps and desktop clients**. Leave other items unchecked.
94+
1. Select **Done**.
95+
1. Under **Access controls** > **Session**, select **Require token protection for sign-in sessions** and select **Select**.
96+
1. Confirm your settings and set **Enable policy** to **Report-only**.
97+
1. Select **Create** to create to enable your policy.
98+
99+
After confirming your settings using [report-only mode](howto-conditional-access-insights-reporting.md), an administrator can move the **Enable policy** toggle from **Report-only** to **On**.
100+
101+
### Capture logs and analyze
102+
103+
Monitoring Conditional Access enforcement of token protection before and after enforcement.
104+
105+
#### Sign-in logs
106+
107+
Use Azure AD sign-in log to verify the outcome of a token protection enforcement policy in report only mode or in enabled mode.
108+
109+
1. Sign in to the **Azure portal** as a Conditional Access Administrator, Security Administrator, or Global Administrator.
110+
1. Browse to **Azure Active Directory** > **Sign-in logs**.
111+
1. Select a specific request to determine if the policy is applied or not.
112+
1. Go to the **Conditional Access** or **Report-Only** pane depending on its state and select the name of your policy requiring token protection.
113+
1. Under **Session Controls** check to see if the policy requirements were satisfied or not.
114+
115+
:::image type="content" source="media/concept-token-protection/sign-in-log-sample.png" alt-text="Screenshot showing an example of a policy not being satisfied." lightbox="media/concept-token-protection/sign-in-log-sample.png":::
116+
117+
#### Log Analytics
118+
119+
You can also use [Log Analytics](../reports-monitoring/tutorial-log-analytics-wizard.md) to query the sign-in logs (interactive and non-interactive) for blocked requests due to token protection enforcement failure.
120+
121+
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**.
122+
123+
```kusto
124+
//Per Apps query
125+
// Select the log you want to query (SigninLogs or AADNonInteractiveUserSignInLogs )
126+
//SigninLogs
127+
AADNonInteractiveUserSignInLogs
128+
// Adjust the time range below
129+
| where TimeGenerated > ago(7d)
130+
| project Id,ConditionalAccessPolicies, Status,UserPrincipalName, AppDisplayName, ResourceDisplayName
131+
| where ConditionalAccessPolicies != "[]"
132+
| where ResourceDisplayName == "Office 365 Exchange Online" or ResourceDisplayName =="Office 365 SharePoint Online"
133+
//Add userPrinicpalName if you want to filter
134+
// | where UserPrincipalName =="<user_principal_Name>"
135+
| mv-expand todynamic(ConditionalAccessPolicies)
136+
| where ConditionalAccessPolicies ["enforcedSessionControls"] contains '["Protection"]'
137+
| where ConditionalAccessPolicies.result !="reportOnlyNotApplied" and ConditionalAccessPolicies.result !="notApplied"
138+
| extend SessionNotSatisfyResult = ConditionalAccessPolicies["sessionControlsNotSatisfied"]
139+
| extend Result = case (SessionNotSatisfyResult contains 'Protection', 'Block','Allow')
140+
| summarize by Id,UserPrincipalName, AppDisplayName, Result
141+
| summarize Requests = count(), Users = dcount(UserPrincipalName), Block = countif(Result == "Block"), Allow = countif(Result == "Allow"), BlockedUsers = dcountif(UserPrincipalName, Result == "Block") by AppDisplayName
142+
| extend PctAllowed = round(100.0 * Allow/(Allow+Block), 2)
143+
| sort by Requests desc
144+
```
145+
146+
The result of the previous query should be similar to the following screenshot:
147+
148+
:::image type="content" source="media/concept-token-protection/log-analytics-results.png" alt-text="Screenshot showing example results of a Log Analytics query looking for token protection policies" lightbox="media/concept-token-protection/log-analytics-results.png":::
149+
150+
The following query example looks at the non-interactive sign-in log for the last seven days, highlighting **Blocked** versus **Allowed** requests by **User**.
151+
152+
```kusto
153+
//Per users query
154+
// Select the log you want to query (SigninLogs or AADNonInteractiveUserSignInLogs )
155+
//SigninLogs
156+
AADNonInteractiveUserSignInLogs
157+
// Adjust the time range below
158+
| where TimeGenerated > ago(7d)
159+
| project Id,ConditionalAccessPolicies, UserPrincipalName, AppDisplayName, ResourceDisplayName
160+
| where ConditionalAccessPolicies != "[]"
161+
| where ResourceDisplayName == "Office 365 Exchange Online" or ResourceDisplayName =="Office 365 SharePoint Online"
162+
//Add userPrincipalName if you want to filter
163+
// | where UserPrincipalName =="<user_principal_Name>"
164+
| mv-expand todynamic(ConditionalAccessPolicies)
165+
| where ConditionalAccessPolicies.enforcedSessionControls contains '["Protection"]'
166+
| where ConditionalAccessPolicies.result !="reportOnlyNotApplied" and ConditionalAccessPolicies.result !="notApplied"
167+
| extend SessionNotSatisfyResult = ConditionalAccessPolicies.sessionControlsNotSatisfied
168+
| extend Result = case (SessionNotSatisfyResult contains 'Protection', 'Block','Allow')
169+
| summarize by Id, UserPrincipalName, AppDisplayName, ResourceDisplayName,Result
170+
| summarize Requests = count(),Block = countif(Result == "Block"), Allow = countif(Result == "Allow") by UserPrincipalName, AppDisplayName,ResourceDisplayName
171+
| extend PctAllowed = round(100.0 * Allow/(Allow+Block), 2)
172+
| sort by UserPrincipalName asc
173+
```
174+
175+
## Next steps
176+
177+
- [What is a Primary Refresh Token?](../devices/concept-primary-refresh-token.md)
Loading
668 KB
Loading
27.6 KB
Loading
430 KB
Loading

0 commit comments

Comments
 (0)