‹ Back to list
Stay InformedCC00190

Instant revocation of service principal bearer tokens with CAE

Services: TECHCOMMUNITY.MICROSOFT.COM· Published: 2026-08-26· MS modified: 2026-08-26· View source ↗
What's new

Microsoft announcement

Introduction

Workload identities such as service principals are an important part of the attack surface in Entra: they are often used by critical automated processes, and they can carry privileged and sensitive permissions. The authentication flow used by these principals is the Client Credential flow, which results in an access token.

In this blog post, I'll describe how Continuous Access Evaluation (CAE) can be leveraged to instantly invalidate an access token for a service principal in Microsoft Entra. This is incredibly valuable as part of a kill-switch in incident response scenarios.

Access tokens (aka bearer tokens)

Access tokens are bearer tokens. Instant invalidation of bearer tokens is an important response capability because normally these tokens have a lifetime between 60 and 90 minutes.

This is a long time in scenarios where a compromised token can be used for triggering malicious automation by a bad actor.

How to enable CAE for service principal tokens

CAE is enabled by a “client capability” claim, “xms_cc”, with the value of “cp1”.

The screenshot below shows an example of a PowerShell function that incorporates this:

Recognizing a CAE-enabled token 

The access token I get back from this request is base 64 encoded. I can echo this base 54 encoded value back in my PowerShell session, then paste it into a decoder to investigate it (jwt.io or jwt.ms).

The first thing you will notice is the presence of this claim:

The second thing you will notice is the lifetime of the token:

The expiry value is now (roughly) 24 hours after the “iat” (issued at) time, instead of the 60-90 minutes that we normally see in tokens that are not CAE-enabled.

Why does this matter

Although a longer lifetime seems less secure, Microsoft’s philosophy around this is that with Workload Identity Protection enabled, risk levels can dynamically be picked up for the identity.

If an identity is at a high risk level, the token is revoked within a couple of minutes automatically.

High risk is only one of three revocation events. At the time of writing, the revocation events are:

  • Service Principal at high risk
  • Service Principal disabled
  • Service Principal deleted

How to manually test this

In PowerShell, I use the “Connect-And-GetToken" function above to obtain the token and construct a header, which I then use to call a Graph endpoint:

 

(I can call this https://graph.microsoft.com/v1.0/users endpoint, because my app, represented by $cid, has the User.Read.All API permission. This is not relevant for this topic, just an example for demo purposes).

Whilst the bearer token (in the header) is still valid, the response that comes back can be something like this:

If this were not a CAE-enabled token, even removing the service principal, changing its password or disabling it, would NOT stop me from doing this, as long as the bearer token lifetime has not expired!

Now let’s trigger revocation manually.

I will describe two of the three revocation events: high risk and disablement.

Test 1:  Simulate service principal at high risk

To simulate putting the service principal at risk level high, we use another service principal that has the API permission “IdentityRiskyServicePrincipal.ReadWrite.All”.

With this other identity (connect-MgGraph), issue this command:

Confirm-MgRiskyServicePrincipalCompromised -ServicePrincipalIds @("{Object id of our target service principal}”)        

After a short while, the identity shows as high risk in the portal (under Identity Protection > Risk workload identities).

Now, when I try to use the same header with the same access token from before, the response I get is:

“Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.”

This means that the access token was effectively revoked and the revocation objective was achieved.

To dismiss (cancel) the risk status on that service principal, click on “Dismiss service principal(s) risk” in the portal (top bar), or use Invoke-MgDismissRiskyServicePrincipal in PowerShell.

After this risk dismissal, my token and the header containing it are still invalid, so I have to re-authenticate (in my case with the “Connect-And-GetToken” function) if I again want to make the call to Graph.

‼️This brings me to an important point: this option must be paired with Conditional Access for Workload Identities, using a policy that BLOCKS authentication in case the risk level is high.‼️

Without this, my token may be revoked by the risk event, but a bad actor that also owns the client ID and secret could, in theory, re-authenticate and get a new token that subsequently does not get revoked as the revocation event on the previous token is in the past (unless a new risk event is picked up).

Conditional Access for workload identities requires a Workload Identity Premium license.

Test 2: Simulate service principal disabled

A simpler and faster option for revoking a CAE-enabled service principal access token is to disable the service principal.

For this, I use the Graph Explorer in my lab:

‼️Notice that this must be done directly on the service principal. Deactivating the registered app also disables the service principal, but it does not trigger the revocation event.‼️

This instantly gives me a “(401) Unauthorized if I try to reuse the header (with the token), and therefore it is a better manual kill switch option.

I was able to do this in a tenant without a Workload Identity Premium license.

Microsoft Entra Sign-in logs

Service principals have their own section in the Microsoft Entra Sign-in log.

If the token issued (after the sign-in was successful) was CAE enabled, the “Basic in” tab of the sign-in event will show a line "Continuous access evaluation Yes",

Under “Additional details”, you will see:

Warning

The risk level may be reaching "high" without your input, which leads to automatic revocation for CAE-enabled tokens.

Detections at the time of writing include:

  • Microsoft Entra threat intelligence
  • Suspicious Sign-ins
  • Admin confirmed service principal compromised (as we have done in this blog)
  • Leaked Credentials
  • Malicious application
  • Suspicious application
  • Anomalous service principal activity
  • Suspicious API Traffic

Securing workload identities with Microsoft Entra ID Protection - Microsoft Entra ID Protection | Microsoft Learn

Conclusion

To create the ability to revoke access tokens before the end of their lifetime,  enable the "cp1" client capability claim at integration time (when building your solutions and their authentication call). 

You cannot revoke service principal access tokens that were not created with the client capabilities claim of “cp1” in the first place.

Please refer to Continuous access evaluation for workload identities in Microsoft Entra ID - Microsoft Entra ID | Microsoft Learn for an up-to-date list of possibilities and limitations for this feature.

I am currently researching if this can be used in Agent flows, where the token exchange pattern applies, so stay tuned.

Learn more

Access token claims reference - Microsoft identity platform | Microsoft Learn

Microsoft Entra Conditional Access for workload identities - Microsoft Entra ID | Microsoft Learn

Continuous access evaluation for workload identities in Microsoft Entra ID - Microsoft Entra ID | Microsoft Learn

Graph Explorer | Try Microsoft Graph APIs - Microsoft Graph

Securing workload identities with Microsoft Entra ID Protection - Microsoft Entra ID Protection | Microsoft Learn

Source

Public Microsoft post (not observed by a tenant):
https://techcommunity.microsoft.com/blog/microsoft-entra-blog/instant-revocation-of-service-principal-bearer-tokens-with-cae/4548192

Change history