I have a vendor application, possibly a SAAS application that want to access my key Vault in my Azure tenant, which is behind a firewall. Can anyone the suggest the best way to give the vendor access to my key vault? please drop a comment if you have done this before.
There are 2 ways, from which you can give the External vendor application access to your Azure key vault.
You can create a new service principal/app registration in your Azure AD tenant which will model the vendor application and provide that service principal access to key vault secrets and certificates, Via adding that service principal to the access policy with RBAC role. And then giving your vendor the Application client ID, Application secret, Tenant ID to use this app in their SAAS vendor app code for authentication to Key vault in your tenant. If the SAAS Vendor application already resides in your tenant, This method will work too.
I created a key vault resource on Azure :-
I created one single Tenant App to use for this tenant and then added that app to the access policy of Azure key vault.
Select your key vault from Azure Portal> Left pane> Access Policies> Add> Select the secret, key and certificate permissions as required > In Principal select your Single Tenant App> Next> Create
Singletenantapp is added to access policies with below permissions on Key vault:-
Now, You can provide this singletenantkeyvault application’s > tenant Id, application client ID, secret to the SAAS vendor application code as this Singletenantkeyvault application will model your real world SAAS vendor application.
Example-
{
"DNSNameKeyVault": "https://siliconkeyvault123.vault.azure.net/",
"AADAppRegistrationAppId": "7dad56d0-29d7-4d14-8dbe-4b9787895942",
"AADAppRegistrationAppSecret": "<app-secret>",
"SomeSecret": "DEV_VALUE"
}
Similar settings should be added to your SAAS vendor’s application’s appsettings.json folder depending on the framework that the SAAS vendor’s app runs on.
Note- Access policies can only be added to the Users and Applications in your directory only, you cannot add access policies to the external application that resides in other tenant/directory. You can either create a new application in your tenant or enable Multi-tenant application.
You can create a multi-tenant app shared between your External SAAS vendor’s tenant and your tenant, And assign the Key vault access policy to that Multi-tenant App. In this way you can use the existing SAAS vendor app in their tenant with your tenant to only give least privileged access to control Key vault.
I created a multi-tenant asp.net core app in my Default Directory tenant: -
MultiTenantAuth App is created successfully in our Azure AD Default Directory tenant
You can also create a multi-tenant app within Azure AD portal like below:-
Now, either you can authenticate with your SAS vendor application with your tenant and access key vault via running the code from VS studio or you can call this endpoint and replace the SAS vendor’s tenant ID with yours to get the SAAS vendor application from their tenant to your tenant and then provide the required access:-
In this example- Your MultiTenantDemo or MultiTenantAuth app is your SAAS vendor’s tenant Application which will be added in your or other tenant by either running the code or by calling the below endpoint.
In this example- I created MultiTenantDemo, MultiTenantAuth applications in my Default Directory and now I am adding them in my other directory SiliconSid.
https://login.microsoftonline.com/tenantid/adminconsent?client_id=clientid&state=12345&redirect_uri=http://localhost/myapp/permissions
I logged in with my another tenant’s admin user and accepted the consent for the app from my default directory to the new directory
After I called this endpoint, the Application is added in my another directory SILICONSID:-
Now, I’ll add this application in the Access policy of my key vault :-
Is inviting the user from your SAAS vendor’s tenant to your tenant and giving the user access to your key vault access policy if your saas vendor real world application uses username and password as authentication and not Service principal.
You can invite your SAAS vendor’s user like below:-
Invite the user and only provide the user access to your key vault:-
You can invite the SAAS vendor user via Email
An invitation link will be sent to the user’s email once the user accepts the invitation, He is redirected to your Azure Portal and is added in your Azure AD.
The SAAS vendor user can log in to Azure Portal and select your directory> and access the Key vault given you added that user to your access policy like below:-
You can again apply the policy of least privileged here and provide user only the access to the key vault and nothing else. You also need to provide the invited user access to your Subscription’s Key vault resource group with key vault role to only read key vault. This can be used if your SAAS vendor real world application uses Username and password as authentication in their Code and not service principal application.
The best way here is to either create a new application in your tenant or to create a multi-tenant application. Point 3) is not recommended and is not a best security practice.
Reference:
Azure Key Vault considerations for multitenancy - Azure Architecture Center | Microsoft Learn
Related
We previously used keyvault and connectionstring to access resources in azure. However it will generate many parameters needed. We want to simplify the process.
We wanted to use aad authentication.
Firstly, we tried certificate-based aad authentication https://learn.microsoft.com/en-us/azure/cosmos-db/sql/certificate-based-authentication first, it works. But the thing is, in keyvault the certificates are set auto-rotation, but in aad app, we can only manually upload new certificate each time (I know there are methods like VM extension or extra software can do auto renewal, but it's complicated. We just want change configs in azure portal and change service code to access.) In this situation, when certificates becomes more and more, it's not suitable to manually renew each cert in each aad app. I notice in some places it says setting tls/ssl settings which makes auto-renewal, but currently in azure portal, it just can manually upload certificates. Only in function app can do tls/ssl settings.
Secondly, then we notice another one as managed identity. It simply says azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/"); to get token. But the thing is, current login tenantid is microsoft.onmicrosoft.com, but the resources and the subscriptions are all in prdtrs01.onmicrosoft.com through torus account.
Even I try with string accessToken = azureServiceTokenProvider.GetAccessTokenAsync("https://management.azure.com/", prdtrs01tenantid) still does not work, saying AADSTS50020: User account '{EmailHidden}' from identity provider '...' does not exist in tenant 'PRDTRS01' and cannot access the application '...'. It seems just cannot get token from prdtrs01 tenantid.
Also, I tried to replace the aad app used in first method with the function app used in second method to do certificate-based authentication. However the function app does not have a clientid, just principalId and user managed identity's clientid. Both ids fail with ClientAssertionCertificate credential = new ClientAssertionCertificate(clientId, cert); in certificate-based authentication. It finally says "Client assertion contains an invalid signature. [Reason - The key was not found., Thumbprint of key used by client".
In all, I described several ways we tried, but all failed. Can anyone help?
Thanks
AADSTS50020: User account '{EmailHidden}' from identity provider
'...' does not exist in tenant 'PRDTRS01' and cannot access the
application
As per this first error , it means that the account you are using to access the application is not a part of the tenant that the application is hosted on.
Make the application as a Multi-Tenant Application :
You can convert the application to accept users from multiple tenants. In this way you can give access to users who are not in your tenant without having to add them to the tenant where the application is in.
Maybe account type is set to Accounts in this organizational directory only.
You may have to change it to Accounts in any organizational directory.
Go to Azure portal -> Azure Active Directory -> Manage -> App Registrations --> your app name -> Supported Account Types
(or)
Add the user to the tenant as guest :
You may need to add the user to the tenant that the application is hosted in. You can follow this document to add the user with your domain as a Guest User to the tenant. And grant access to the application for the said user.
However, if your authentication call is for specific tenant i.e., https://login.microsoftonline.com/yourtenantname or_id, users from other organizations won't be able to access the application and are required to be added as guests in the tenant specified in the request.
In your case, try to authenticate request like https://login.microsoftonline.com/organizations or https://login.microsoftonline.com/common
General Overview of what I am trying to achieve
I am trying to build an Azure AD Multitenant Web application which allows me to manage resources in customer subscriptions/tenants using the Azure Resource Manager (ARM) APIs. I am pretty new to Azure AD Multitenancy.
The Ideal control flow
1. A customer browses the Applications (ideal an admin of the customer tenant)
2. Will be granted with Azure AD authorize flow
3. Accepts everything and grants admin consent for the AD App in their tenant
4. Unclear: The AD App will be granted contributer access on a subscription or resource
5. My Web App will be able to use the AD App credentials to manage the customer resources using the ARM APIs
Problem
Steps 1-3, 5: Are clear and I know how to build that.
Step 4: I am not sure how to build that so that step happens automatically.
Solutions I have considered
The worst case would be the customer AD Admin must manually grant the AD App access to a subscription or resource using the Azure Portal.
One idea that came to my mind is that you require the user_impersonation permission on Azure Service Management API.
After the user logs in, you could list out the subscriptions available, allowing the user to select one.
Then list out the resource groups if needed.
Once the user confirms a selection, your app could add itself as a Contributor on the targeted resource through the Management API, on behalf of the currently signed-in user.
To do this, you will need the object id of the service principal for your app created in the target tenant.
You can get it by acquiring an app-only token for e.g. the Azure Management API from that tenant's token endpoint after the user has logged in.
The token will contain an oid claim, which is the object id for the service principal.
Of course the user who signs in would have to have the ability to modify access to the target resource.
I would say the downside of this approach is that the organization must trust your app to only do the thing it claims to do.
The approach where they grant the access manually allows them to be in control fully.
Azure Active Directory has applications and service principals.
https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
Both objects seem to have credentials.
New-AzureADApplicationPasswordCredential
New-AzureADServicePrincipalPasswordCredential
If both a service principal and an application object have credential(for example password), which one is used for authentication? If service principal's credential is used, what's the purpose of application object's credential? Is it for fallback when a service princial doesn't have credential?
I read this question, but I cannot understand the difference between application's password and service principal's one.
Authentication difference between using AAD app key and Service Principal Password
Both of the two passwords can be used to authenticate, but the password of the service principal just can be used to authenticate in the tenant which it located in, the password of the application can be used to authenticate in all the tenants where its service principal instances located.
The service principal is just a instance of the application in a specific tenant, when a tenant consent an application, azure will install it as an Enterprise Application(i.e. serivice principal) in the tenant. There can be several service principals in different tenants, but the application is the only.
My target is simple: use an Azure AD multi-tenant app to be able to call Azure Resource Manager API on other tenants. However, I cannot figure out how to do it when you sign in with a personal Microsoft account.
I created an Azure AD multi-tenant app using a company's tenant
Then created a test ASP.NET Core Web application which goes to a such URL:
The Microsoft's login page shows up and I'm able to log in successfully with a personal LIVE.COM, where the test Web app receives the callback with given redirect URL. I have another Azure tenant created with my personal MS account which I'm trying to access.
The Multi-Tenant AAD App gets added to the "personal space" at https://account.live.com/consent/Manage, but not to the Azure AD tenant.
It probably makes sense from the technical standpoint, but how do I add the AAD app to another tenant when logged in with a personal account?
I figured that the "authorize" URL must include the AAD tenant name/ID instead of "common" (confirm that a Service Principal gets created on the target tenant):
However, that tenant name/ID is unknown when a user logs in, and I don't really know what API to use to query it.
Should be done by hand - detecting a personal MS account and finding the association with AAD tenant, or is there an API that can facilitate this? In both cases, how? What if an account is associated with multiple tenants ("Switch Directory" in Azure Portal)?
P.S. using URLs https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize ("orgainzations" instead of "common") or https://login.microsoftonline.com/common/oauth2/authorize (without "v2.0") won't allow using a personal MS account to log in.
UPDATE
To demonstrate the problem, there are 4 tests were made to access resource "https://management.azure.com/" with a multi-tenant app:
Authorize Microsoft's "Microsoft Azure" app with v1 endpoint - it works with personal accounts:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&response_type=code&response_mode=form_post&resource=https://management.azure.com/&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize the same "Microsoft Azure" app with v2 endpoint - now it does not allow to use personal accounts:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=1950a258-227b-4e31-a9cf-717495945fc2&response_type=code&response_mode=form_post&scope=https://management.azure.com/.default&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize a custom multitenant app against v1 endpoint (insert your client id) - shows error AADSTS50020 "User account 'user#live.com' from identity provider 'live.com' does not exist in tenant 'contoso.com' and cannot access the application ''(app name) in that tenant. The account needs to be added as an external user in the tenant first. Sign out and sign in again with a different Azure Active Directory user account."
https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&response_mode=form_post&resource=https://management.azure.com/&nonce=123&state=common&redirect_uri=http%3A%2F%2Flocalhost%3A64696%2FAuthCallback
Authorize a custom multitenant app against v2 endpoint - same as test #2 - does not allow personal accounts.
Thoughts.
The v2 endpoint does not allow personal accounts for the resource https://management.azure.com/, where the v1 endpoint does.
Microsoft Azure app probably has a manifest with undocumented or hardcoded settings that allows to use personal accounts for the desired resource.
ANSWER
Long story short, it's not possible for general public as per Microsoft.
Only V2.0 endpoint supports personal account(even it doesn't belong to any Azure AD tenants) to login.
It works with personal account when you use v1.0 endpoint.
That's because that personal account belongs to at least one Azure AD tenant. Then this personal account will be recognized as a guest user in the tenant.
The v2 endpoint does not allow personal accounts for the resource
https://management.azure.com/
Yes, if you login in with personal account when you use v2.0 endpoint, it will detect that you belong to personal account and will redirect you to the personal account login endpoint https://login.live.com/oauth20_authorize.srf.
You must identify the tenant to login in with personal account when use v2.0 endpoint
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?
client_id=20244877-ae8f-4325-b4cf-c6dc239cb124
&response_type=code
&redirect_uri=https://localhost
&response_mode=fragment
&scope=https://management.azure.com/.default
&state=12345
&nonce=default
Then you can call https://management.azure.com/tenants?api-version=2016-06-01 to list all the tenants that account belongs to.
Update:
It is normal that you can't do that. You are not telling Azure AD that
the which tenant the MSA user is an external user, so Azure AD is
making a guess and checking in the tenant where the app is registered
(tenant A). If you expect external users to be able to sign in, you
must specify the tenant where the guest has previously been invited to
(e.g. tenant B).
I want to understand the difference between the SPN & UPN in Azure AD Context. My understanding is there are three way to establish identity in Azure AD
Users Key in their username and Password to establish Identity
An application using ClientId and Secret Key to establish Identity
An application using ClientId and Certificate to establish Identity
Is User/Password is called UPN & rest two are called SPN? Also is there any other way to establish identity?
In Azure AD, UPN is the User Principal Name. It is always in the format which looks like an email address. Essentially it has three parts. User account name, the separator (i.e. # symbol) and UPN suffix or domain name. Its primary purpose is to use during the authentication and represents user identity.
SPN is the Service Principal Name. The service principal object defines the policy and permissions for an application, providing the basis for a security principal to represent the application when accessing resources at run-time. App identity (service principal) is preferable to running the app under your own credentials (user identity) because:
You can assign permissions to the app identity that are different than your own permissions. Typically, these permissions are restricted to exactly what the app needs to do.
You do not have to change the app's credentials if your responsibilities change.
You can use a certificate to automate authentication when executing an unattended script.
You could create service principal with password or certificate as you shown.
Please click here for more about application and service principal objects in Azure Active Directory, and click here for how to use portal to create an Azure Active Directory application and service principal that can access resources. You could choose other ways (e.g. PowerShell/CLI) on the left navigation panel.