From d1ee135d91e775cc3c460b0383062a9afa134637 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary Date: Fri, 4 Apr 2025 11:05:41 +0100 Subject: [PATCH 1/7] Update msiv1_token_revocation.md --- docs/msiv1_token_revocation.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index b7986af8b3..11d2c1bde9 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -41,15 +41,19 @@ Steps 5-9 are new and show how the RP propagates the revocation signal. ### Explanation: 1. The client (CX) calls some **Resource** with token **T**. 2. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. -3. CX parses **C** and calls **MSAL** with `.WithClaims(C).WithClientCapabilities(cp1)`. -4. MSAL sees the local cached token is "bad" → triggers a refresh flow. -5. MSAL calls **MITS** with `xms_cc=cp1&token_sha256_to_refresh=SHA256(T)`. -6. **MITS** is basically a proxy, forwarding the query to **SFRP**. -7. **SFRP** uses MSAL again to get a **new** token from eSTS. +3. CX parses **C** and calls **MSAL** **Client** with `.WithClientCapabilities(cp1)`. +4. MSAL calls **AcquireToken** with `.WithClaims(C)`. +5. MSAL sees the local cached token is "bad" → triggers a refresh flow. +6. MSAL calls **MITS** with `xms_cc=cp1&token_sha256_to_refresh=SHA256(T)`. +7. **MITS** is basically a proxy, forwarding the query to **SFRP**. +8. **SFRP** uses MSAL again to get a **new** token from eSTS. > [!IMPORTANT] > This design is only applicable to MIRP api-version=2025-03-30 (for App Service). api-version for service fabric will be soon made available. +> [!NOTE] +> The `token_sha256_to_refresh=SHA256(T)` here the SHA256 converts the token into a SHA256 string. Example - "examplestring" -> output + > [!NOTE] > ClientCapabilities is an array of capabilities. In case the app developer sends multiple capabilities, these will be sent to the RP as `MITS_endpoint?xms_cc=cp1,cp2,cp3`. The RP MUST pass "cp1" (i.e. the CAE capabilitiy) if it is included. From be378bfb9b0c834d776510afd3846393fc2f70b4 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary <107404295+4gust@users.noreply.github.com> Date: Fri, 4 Apr 2025 15:23:52 +0100 Subject: [PATCH 2/7] Update token revocation documentation with detailed steps --- docs/msiv1_token_revocation.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index 11d2c1bde9..e1af3595d9 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -41,18 +41,20 @@ Steps 5-9 are new and show how the RP propagates the revocation signal. ### Explanation: 1. The client (CX) calls some **Resource** with token **T**. 2. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. -3. CX parses **C** and calls **MSAL** **Client** with `.WithClientCapabilities(cp1)`. -4. MSAL calls **AcquireToken** with `.WithClaims(C)`. -5. MSAL sees the local cached token is "bad" → triggers a refresh flow. +3. CX creates an **MSAL** **Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. +4. CX parses the WWW-Authenticate header, extracts the claims **C** and uses MSAL **AcquireToken** with `.WithClaims(C)`. +5. MSAL inspects its cache first. If it finds a token, the token is considered to have been revoked. MSAL needs to tell the token issuer about it, so that the token issuer can also bypass its own cache. 6. MSAL calls **MITS** with `xms_cc=cp1&token_sha256_to_refresh=SHA256(T)`. -7. **MITS** is basically a proxy, forwarding the query to **SFRP**. +7. The token issuer uses the information to bypass its own caches and to get a new token from eSTS. 8. **SFRP** uses MSAL again to get a **new** token from eSTS. > [!IMPORTANT] > This design is only applicable to MIRP api-version=2025-03-30 (for App Service). api-version for service fabric will be soon made available. > [!NOTE] -> The `token_sha256_to_refresh=SHA256(T)` here the SHA256 converts the token into a SHA256 string. Example - "examplestring" -> output +> The SHA256 conversion is done by doing a Base64-encoded SHA-256 hash of the token (UTF-8). For example: Convert.ToBase64String(SHA256(Encoding.UTF8.GetBytes(accessToken))). +> Example - "test_token" -> "zAr5codUO2XaLH4UdkJgIYJsqxZvHgY+0BK4Vf+BllY=" + > [!NOTE] > ClientCapabilities is an array of capabilities. In case the app developer sends multiple capabilities, these will be sent to the RP as `MITS_endpoint?xms_cc=cp1,cp2,cp3`. The RP MUST pass "cp1" (i.e. the CAE capabilitiy) if it is included. From db3ee1bff51fcf50e83c6ca8ee45161d2c29644a Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary Date: Mon, 7 Apr 2025 10:54:09 +0100 Subject: [PATCH 3/7] Update msiv1_token_revocation.md --- docs/msiv1_token_revocation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index e1af3595d9..ffe391e321 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -53,7 +53,7 @@ Steps 5-9 are new and show how the RP propagates the revocation signal. > [!NOTE] > The SHA256 conversion is done by doing a Base64-encoded SHA-256 hash of the token (UTF-8). For example: Convert.ToBase64String(SHA256(Encoding.UTF8.GetBytes(accessToken))). -> Example - "test_token" -> "zAr5codUO2XaLH4UdkJgIYJsqxZvHgY+0BK4Vf+BllY=" +> Example - "test_token" -> "cc0af97287543b65da2c7e1476426021826cab166f1e063ed012b855ff819656" > [!NOTE] From 28e3795384c6e35bbebface41f71f1b26ad7637f Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary Date: Mon, 7 Apr 2025 11:12:45 +0100 Subject: [PATCH 4/7] Update msiv1_token_revocation.md --- docs/msiv1_token_revocation.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index ffe391e321..2ffc22694e 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -39,9 +39,9 @@ Steps 1-4 fall to the Client (i.e. application using MSI directly or higher leve Steps 5-9 are new and show how the RP propagates the revocation signal. ### Explanation: -1. The client (CX) calls some **Resource** with token **T**. -2. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. -3. CX creates an **MSAL** **Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. +1. CX creates an **MSAL** **Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. +2. The client (CX) calls some **Resource** with token **T**. +3. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. 4. CX parses the WWW-Authenticate header, extracts the claims **C** and uses MSAL **AcquireToken** with `.WithClaims(C)`. 5. MSAL inspects its cache first. If it finds a token, the token is considered to have been revoked. MSAL needs to tell the token issuer about it, so that the token issuer can also bypass its own cache. 6. MSAL calls **MITS** with `xms_cc=cp1&token_sha256_to_refresh=SHA256(T)`. From dde0082b4bc2566fc551b29a8b441e53a3619595 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary Date: Tue, 8 Apr 2025 11:51:27 +0100 Subject: [PATCH 5/7] Update msiv1_token_revocation.md --- docs/msiv1_token_revocation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index 2ffc22694e..4b5aabfe33 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -39,7 +39,7 @@ Steps 1-4 fall to the Client (i.e. application using MSI directly or higher leve Steps 5-9 are new and show how the RP propagates the revocation signal. ### Explanation: -1. CX creates an **MSAL** **Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. +1. CX creates an **MSAL Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. 2. The client (CX) calls some **Resource** with token **T**. 3. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. 4. CX parses the WWW-Authenticate header, extracts the claims **C** and uses MSAL **AcquireToken** with `.WithClaims(C)`. @@ -52,7 +52,7 @@ Steps 5-9 are new and show how the RP propagates the revocation signal. > This design is only applicable to MIRP api-version=2025-03-30 (for App Service). api-version for service fabric will be soon made available. > [!NOTE] -> The SHA256 conversion is done by doing a Base64-encoded SHA-256 hash of the token (UTF-8). For example: Convert.ToBase64String(SHA256(Encoding.UTF8.GetBytes(accessToken))). +> The SHA256 conversion is done by doing a Hex-encoded SHA-256 hash of the token (UTF-8). For example: BitConverter.ToString(SHA256(Encoding.UTF8.GetBytes(accessToken))). > Example - "test_token" -> "cc0af97287543b65da2c7e1476426021826cab166f1e063ed012b855ff819656" From 497f7c18adcbfa60094b5cc39dea0570255ec5c5 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary <107404295+4gust@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:48:05 +0100 Subject: [PATCH 6/7] Update docs/msiv1_token_revocation.md Co-authored-by: Ray Luo --- docs/msiv1_token_revocation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index 4b5aabfe33..ac50f0a59c 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -45,7 +45,7 @@ Steps 5-9 are new and show how the RP propagates the revocation signal. 4. CX parses the WWW-Authenticate header, extracts the claims **C** and uses MSAL **AcquireToken** with `.WithClaims(C)`. 5. MSAL inspects its cache first. If it finds a token, the token is considered to have been revoked. MSAL needs to tell the token issuer about it, so that the token issuer can also bypass its own cache. 6. MSAL calls **MITS** with `xms_cc=cp1&token_sha256_to_refresh=SHA256(T)`. -7. The token issuer uses the information to bypass its own caches and to get a new token from eSTS. +7. **MITS** uses the information to bypass its own caches and to get a new token from its upstream **SFRP**. 8. **SFRP** uses MSAL again to get a **new** token from eSTS. > [!IMPORTANT] From 7910491a3551a579efe6c9b793c3f250f4c2e491 Mon Sep 17 00:00:00 2001 From: Nilesh Choudhary <107404295+4gust@users.noreply.github.com> Date: Wed, 9 Apr 2025 11:48:23 +0100 Subject: [PATCH 7/7] Update docs/msiv1_token_revocation.md Co-authored-by: Ray Luo --- docs/msiv1_token_revocation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/msiv1_token_revocation.md b/docs/msiv1_token_revocation.md index ac50f0a59c..e6a4db2e4a 100644 --- a/docs/msiv1_token_revocation.md +++ b/docs/msiv1_token_revocation.md @@ -39,7 +39,7 @@ Steps 1-4 fall to the Client (i.e. application using MSI directly or higher leve Steps 5-9 are new and show how the RP propagates the revocation signal. ### Explanation: -1. CX creates an **MSAL Client** with `.WithClientCapabilities(cp1)`, to let the token issuer that it is capable of handling token revocations. +1. CX creates an **MSAL Client** with `.WithClientCapabilities(cp1)`, to let the token issuer know that it is capable of handling token revocations. 2. The client (CX) calls some **Resource** with token **T**. 3. The resource detects **T** is bad (revoked) and returns **401** + **claims C**. 4. CX parses the WWW-Authenticate header, extracts the claims **C** and uses MSAL **AcquireToken** with `.WithClaims(C)`.