I faced an access issue when I tried to access Azure Repository information in one tenant using app credentials from another tenant.
Flow inside only one tenant (works).
I have created a multi-tenant app registration in "Tenant_A" in Azure Portal Entra ID. The link for admin consent looks like this:
https://login.microsoftonline.com/common/adminconsent?client_id=<MY_CLIENT_ID>
I have an Azure DevOps organization "OrgInTenant_A" connected to my Microsoft Entra Default Directory (where the app is created).
I have consented my app using the link mentioned above and added this app as a service principal user to my Azure DevOps Repos "OrgInTenant_A" organization and granted this service principal Basic access and "Project Administrator" role to my project.
After that, I can obtain an access token using only the credentials of my app (Tenant ID, Application (client) ID, and Client Secret) programmatically using NodeJS script and the
'@azure/identity'
package. The scope I am using forgetToken(...)
:499b84ac-1321-427f-aa17-267ca6975798/.default
With this access token, I can get a project list from Azure DevOps "OrgInTenant_A", and also I can clone the repository via git CLI using this token.
So everything works as expected up to this point!
Multi-tenant flow (not works).
The interesting part begins when I try to access projects/repos in another tenant.
I have created a second "Tenant_B" using another Microsoft account. Did the same admin consent using the same URL from Step 1.
I added the service principal as a user in "OrgInTenant_B" Azure DevOps Org in "Tenant_B" with the same access settings. "OrgInTenant_B" connected to
Default Directory
in "Tenant_B".When I try to access projects/repos from "OrgInTenant_B" in "Tenant_B" using app credentials from "Tenant_A", I get the error:
"TF400813: The user '<SOME_UUID>' is not authorized to access this resource."
Questions:
- Q1: What have I missed? What additional steps should I take, or what other permissions/roles/etc should add and where?
- Q2: "<SOME_UUID>" - what does this ID represent? It does not correspond to any numbers that I have: not a Tenant/Client/Secret ID, not an Object ID of the consented app in "Tenant_B".
- Q3: Is it possible at all to access projects/repositories in "OrgInTenant_B" using multi-tenant app credentials from "Tenant_A"?
- Q4: Can it be related to the fact that Azure DevOps API permission has only "Delegated permission" scopes and "Application permission" scopes are disabled? But How it work with only one tenant scenario and does not work in the multi-tenant scenario?
Additional info and steps that I already tried:
I have enabled the toggle
Third-party application access via OAuth
in my "OrgInTenant_B" Settings -> Security -> Policies.I can find the consented app in Azure Portal in the Enterprise Application tab in "Tenant_B", but only when I clear the Application type filter. So I can not see this app when the Application type equals
Enterprise Application
like in "Tenant_A").I already granted admin consent for Default Directory in the Security Permissions tab for this app in "Tenant_B".
My app requires scopes:
- Azure DevOps:
vso.code_full
- Azure DevOps:
vso.project
- Azure DevOps:
user_impersonation
- Also a lot of scopes from
Microsoft Graph
for test purposes
- Azure DevOps:
The multi-tenant application service principal is certainly able to access resources in Azure DevOps.
For your issue, it is most probably that you did not correctly configure the multi-tenant application service principal to your "Tenant_B".
To configure the multi-tenant application service principal:
Ensure you have the any of the following admin roles in the tenants.
Global Administrator
Privileged Role Administrator
Cloud Application Administrator
Application Administrator
When using the consent URL,
ensure you have provided the correct values to.
{organization}
: The tenant ID of your "Tenant_B".{client-id}
: The client ID of the service principal you created in "Tenant_A".After above steps, the service principal should be created and visible in "Tenant_B".
For more details, you can reference the following documentations:
To use the service principal to access resources in "OrgInTenant_A":
To use the service principal to access resources in "OrgInTenant_B":