AADSTS700236: Entra ID tokens issued by issuer 'https://login.microsoftonline.com/<tenant-id>/v2.0' may not be used for federated identity credential flows for applications or managed identities registered in this tenant.

sanderaernouts 30 Reputation points
2025-01-02T13:30:35.89+00:00

I have an application that is running in a subscription backed by Tenant A that needs to authenticate to another service backed by Tenant B. So I'm trying to use the federated credential flow so that I do not have to manage the client secrets.

I'm using a system-assigned managed identity in Tenant A to generate a client assertion (JWT Token). I request this token for the scope "api://AzureADTokenExchange" and then I sent that token as the client assertion for a service principal in Tenant B.

On the app registration in Tenant B I have setup a federated credential, using the "Other Issuer" option and configured the issuer, subject, and left the audience at the default value "api://AzureADTokenExchange". The issuer and subject are correct because I got a different error message earlier.

I checked the error code reference page, but AADSTS700236 is not listed on that page.

It feels like some configuration issue in either Tenant A or Tenant B is preventing me from using a JWT token for a managed identity in tenant A as a federated credential in Tenant B but I cannot find any information on this error code or message.

Has anyone got this working or am I trying to do something that is not possible in the first place?

Here is the code I use right now:

import { AccessToken, ClientAssertionCredential, ClientAssertionCredentialOptions, GetTokenOptions, ManagedIdentityCredential, TokenCredential } from "@azure/identity";

export type ClientAssertionCredentialAdapterOptions = {
  credential: ManagedIdentityCredential;
}

export class ClientAssertionCredentialAdapter implements TokenCredential {
  private clientAssertion: ClientAssertionCredentialAdapterOptions;
  private credential: ClientAssertionCredential;

  constructor(tenantId: string, clientId: string, clientAssertion: ClientAssertionCredentialAdapterOptions, options?: ClientAssertionCredentialOptions) {
    this.clientAssertion = clientAssertion;
    this.credential = new ClientAssertionCredential(tenantId, clientId, () => this.getAssertion(), options);
  }

  getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken | null> {
    return this.credential.getToken(scopes, options);
  }

  private async getAssertion(): Promise<string> {
    const accessToken =  await this.clientAssertion.credential.getToken("api://AzureADTokenExchange"); 
    return accessToken.token;
  }
}
Microsoft Security | Microsoft Entra | Microsoft Entra ID
{count} votes

Accepted answer
  1. Givary-MSFT 35,626 Reputation points Microsoft Employee Moderator
    2025-01-16T16:22:00.7866667+00:00

    @sanderaernouts I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this! Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept " the answer.

    Issue: AADSTS700236: Entra ID tokens issued by issuer 'https://login.microsoftonline.com/<tenant-id>/v2.0' may not be used for federated identity credential flows for applications or managed identities registered in this tenant.

    Solution: Resolved by @sanderaernouts by following the below steps

    I changed my approach a bit and I now have a working scenario for cross-tenant access by using a system-assigned managed identity as a federated credential.

    My test case was to retrieve a list of users in Tenant B using a managed identity from tenant A. I did the following steps to make it work:

    1. create a multi-tenant app registration in Tenant A
    2. add https://www.microsoft.com as the redirect URI (can by anything)
    3. add the Users.Read.All Graph API Application permission
    4. add a managed identity as a federated credential of type Other Issuer
    5. register the multi-tenant app registration in Tenant B by opening https://login.microsoftonline.com/<tenant-b-id>/oauth2/authorize?client_id=<tenant-a-client-id>&response_type=code&redirect_uri=https://www.microsoft.com in my browser
    6. grant tenant-wide admin consent for the required permissions
    7. retrieve an access token for api://AzureADTokenExchange from the local token service endpoint using the system-assigned managed identity
    8. retrieve an access token for the multi-tenant app from the tenant B V2.0 token service endpoint for scope https://graph.microsoft.com/.default passing the access token from the previous step as the value for client_assertion and passing client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    9. invoke https://graph.microsoft.com/v1.0/users passing the token from the previous step in the Authorization header.

    So in essence it's a normal multi-tenant app setup but instead of a client secret or client certificate I used a JWT token for a specific system-assigned managed identity as the client assertion.

    Below is the updated Powershell I run using the Kudu Debug console of an app service with a system-assigned managed identity in tenant A

    $resource = "api://AzureADTokenExchange"
    $endpoint = $env:IDENTITY_ENDPOINT
    $header = $env:IDENTITY_HEADER
    $apiVersion = "2019-08-01"
    $headers = @{ 'X-Identity-Header' = $header }
    $url = "$($endpoint)?api-version=$apiVersion&resource=$resource"
    $client_assertion = Invoke-RestMethod -Method Get -Uri $url -Headers $headers
    $client_assertion.access_token
    $target_tenant=<tenant_b_tenant_id>
    $target_client_id=<multi_tenant_app_registration_client_id>
    $scope="https://graph.microsoft.com/.default"
    $url = "https://login.microsoftonline.com/$target_tenant/oauth2/v2.0/token"
    $body="scope=$scope&client_id=$target_client_id&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&grant_type=client_credentials&client_assertion=$($client_assertion.access_token)"
    $app_registration = Invoke-RestMethod -Method Post -Uri $url -Headers @{ 'Content-Type' = "application/x-www-form-urlencoded"} -Body $body
    $app_registration.access_token
    $response = Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/v1.0/users" -Headers @{ 'Authorization' = "Bearer $($app_registration.access_token)" }
    $response.value
    

    In the above example $response.value is a list of users in tenant B.

    What I still don't understand though is why you cannot use a JWT token from a system-assigned managed identity in a different tenant as a federated credential. This scenario only works for app registrations in the same tenant. However the federated credential scenario Other Issuer seems to imply (to me) that you can use any JWT token from any external identity provider as long as you trust that provider. But if the external identity provider is Entra ID there seems to be some "rules" that are not documented.

    Another strange thing is when you add a system-assigned managed identity as federated credential of scenario Other Issuer (in the same tenant), click Add, and then edit the federated credential scenario is changed to Customer Managed Keys

    add-federated-credential-scenario-other-issuer

    saved-federated-credential

    edit-federated-credential

    If you have any other questions or are still running into more issues, please let me know. Thank you again for your time and patience throughout this issue.

    Please remember to "Accept Answer" if any answer/reply helped, so that others in the community facing similar issues can easily find the solution.

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Vasil Michev 119.9K Reputation points MVP Volunteer Moderator
    2025-01-02T16:33:59.08+00:00

    Afaik that scenario is only supported for user-assigned managed identities.


  2. sanderaernouts 30 Reputation points
    2025-01-08T15:32:03.22+00:00

    I changed my approach a bit and I now have a working scenario for cross-tenant access by using a system-assigned managed identity as a federated credential.

    My test case was to retrieve a list of users in Tenant B using a managed identity from tenant A. I did the following steps to make it work:

    1. create a multi-tenant app registration in Tenant A
    2. add https://www.microsoft.com as the redirect URI (can by anything)
    3. add the Users.Read.All Graph API Application permission
    4. add a managed identity as a federated credential of type Other Issuer
    5. register the multi-tenant app registration in Tenant B by opening https://login.microsoftonline.com/<tenant-b-id>/oauth2/authorize?client_id=<tenant-a-client-id>&response_type=code&redirect_uri=https://www.microsoft.com in my browser
    6. grant tenant-wide admin consent for the required permissions
    7. retrieve an access token for api://AzureADTokenExchange from the local token service endpoint using the system-assigned managed identity
    8. retrieve an access token for the multi-tenant app from the tenant B V2.0 token service endpoint for scope https://graph.microsoft.com/.default passing the access token from the previous step as the value for client_assertion and passing client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
    9. invoke https://graph.microsoft.com/v1.0/users passing the token from the previous step in the Authorization header.

    So in essence it's a normal multi-tenant app setup but instead of a client secret or client certificate I used a JWT token for a specific system-assigned managed identity as the client assertion.

    Below is the updated Powershell I run using the Kudu Debug console of an app service with a system-assigned managed identity in tenant A

    $resource = "api://AzureADTokenExchange"
    $endpoint = $env:IDENTITY_ENDPOINT
    $header = $env:IDENTITY_HEADER
    $apiVersion = "2019-08-01"
    $headers = @{ 'X-Identity-Header' = $header }
    $url = "$($endpoint)?api-version=$apiVersion&resource=$resource"
    
    $client_assertion = Invoke-RestMethod -Method Get -Uri $url -Headers $headers
    $client_assertion.access_token
    
    $target_tenant=<tenant_b_tenant_id>
    $target_client_id=<multi_tenant_app_registration_client_id>
    $scope="https://graph.microsoft.com/.default"
    $url = "https://login.microsoftonline.com/$target_tenant/oauth2/v2.0/token"
    $body="scope=$scope&client_id=$target_client_id&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&grant_type=client_credentials&client_assertion=$($client_assertion.access_token)"
    
    $app_registration = Invoke-RestMethod -Method Post -Uri $url -Headers @{ 'Content-Type' = "application/x-www-form-urlencoded"} -Body $body
    $app_registration.access_token
    
    $response = Invoke-RestMethod -Method Get -Uri "https://graph.microsoft.com/v1.0/users" -Headers @{ 'Authorization' = "Bearer $($app_registration.access_token)" }
    
    $response.value
    

    In the above example $response.value is a list of users in tenant B.

    What I still don't understand though is why you cannot use a JWT token from a system-assigned managed identity in a different tenant as a federated credential. This scenario only works for app registrations in the same tenant. However the federated credential scenario Other Issuer seems to imply (to me) that you can use any JWT token from any external identity provider as long as you trust that provider. But if the external identity provider is Entra ID there seems to be some "rules" that are not documented.

    Another strange thing is when you add a system-assigned managed identity as federated credential of scenario Other Issuer (in the same tenant), click Add, and then edit the federated credential scenario is changed to Customer Managed Keys

    add-federated-credential-scenario-other-issuer

    saved-federated-credential

    edit-federated-credential


  3. Maqsood Ali Bhatti 1 Reputation point
    2025-07-01T13:07:34.78+00:00

    @sanderaernouts Interesting – this is exactly what I’m trying to achieve as well.

    I'm working with a Workforce Tenant (Logic App) using a system-assigned managed identity, and targeting legacy B2C tenants configured with Federated Identity Credential (FIC) using the "Other" type, with the correct issuer and subject.

    However, a few challenges:

    Logic Apps don’t seem to support workload identity token exchange out of the box, especially when calling Microsoft Graph on a B2C tenant.

    It appears that the B2C tenant doesn’t accept the issued token unless Azure Lighthouse is configured, possibly through an OOB (out-of-box) managed identity FIC setup.

    What I’m aiming for is to set up FIC using "Other" type without the added complexity of Azure Lighthouse, if possible.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.