Azure Application Access Only Key Vault Keys - azure

I have a multi-tenant application.
I need this application to:
Be able to read the keys in all vaults of all of the tenants (that grant consent).
Not be able to read any of the secrets.
I manage to get full access to the Vaults using delegated permission (user impersonation).
However that isn't what I want cause this permission provide me with access to the secrets as well.
I saw ( here ) that there's a role for only accessing the keys.
The role name is: Key Vault Crypto Officer (id: 14b46e9e-c2b7-41b4-b07b-48a6ebf60603)
Question is:
Is it possible to make my application require (only?) this role. Which will allow it to read keys but not secrets? Not sure I'm thinking about roles the right way, I don't have a lot of experience with it.
Note that I don't mind asking for delegated / application permissions, if it matters.
Thanks

Note that, it's not possible to read keys in vaults of all tenants using multi-tenant application.
Assigning Key Vault Crypto Officer role to multi-tenant application under subscription gives access in reading only keys of all key vaults in only one tenant linked to that subscription, not other tenants.
I tried to reproduce the same in my environment and got below results:
I created one key vault named srikv07 by selecting Azure role-based access control in Access configuration like below:
In the above keyvault, I created few keys and secrets like this:
Keys:
Secrets:
Now, I registered one multi-tenant Azure AD application named KVmultiapp like below:
Under my subscription, I assigned Key Vault Crypto Officer role to that multi-tenant application:
Go to Azure Portal -> Subscriptions -> Select Subscription -> Access control(IAM) -> Add role assignment
Now, I generated access token using client credentials flow via Postman like below:
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
client_id: <appID>
grant_type:client_credentials
scope: https://vault.azure.net/.default
client_secret: <secret>
Response:
When I used this token to read keys of RBAC enabled key vault, I got error like below:
GET https://<yourkvname>.vault.azure.net//keys?api-version=7.3
Response:
To resolve the error, you need to include tenantID while generating access token like below:
POST https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token
client_id: <appID>
grant_type:client_credentials
scope: https://vault.azure.net/.default
client_secret: <secret>
Response:
Now, I used this token to retrieve keys and got response successfully like below:
GET https://<yourkvname>.vault.azure.net//keys?api-version=7.3
Response:
When I used the same token to get secrets of keyvault, I got 403 Forbidden error as the role gives access to only keys.
GET https://<yourkvname>.vault.azure.net//secrets?api-version=7.3
Response:

Related

Microsoft Azure - Assigning Microsoft Graph permissions to a regular user doesn't work

I understand the process of assigning Microsoft Graph permissions to a service principal. I can take the object id of the Microsoft Graph app, then use the https://graph.microsoft.com/v1.0/servicePrincipals/<id>/appRoleAssignedTo MSGraph endpoint, like described here.
My question is: can I do the same with a regular user? That is, when calling appRoleAssignedTo, specify the object id of a user in the principalId field. Can a regular user have application permissions (like MSGraph permissions), and how do I use them afterwards?
I tried to do the above and assign the RoleManagement.ReadWrite.Directory to a user. Then I logged in with az login and ran az account get-access-token --resource-type ms-graph.
With this token I tried to do an operation that requires the RoleManagement.ReadWrite.Directory permission, like assigning a role to another user, but it fails with Insufficient privileges to complete the operation..
Users can request the scope they need when using Connect-MgGraph, for example:
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"
Which is the recommended approach, as it means that for that session they will only have access to the scopes that are necessary rather than any they've previously requested
I tried to reproduce the same in my environment and got the same error as below:
Note that: Microsoft Graph API permissions can be assigned only to Service principals not users directly.
When I tried to Connect-MgGraph as a normal user, I got the error like below:
Connect-MgGraph -Scopes "RoleManagement.ReadWrite.Directory"
I created an Azure AD Application and granted API permission as below:
I generated access token by using below parameters:
GET https://login.microsoftonline.com/1810a95e-99f3-46e0-84e8-8a2aee05d830/oauth2/v2.0/token
client_id:ClientID
client_secret:*****
scope:RoleManagement.ReadWrite.Directory
grant_type:authorization_code
redirect_uri:RedirectUri
code:code
By using the above access token, I am able to assign directory role to the user successfully as below:
POST https://graph.microsoft.com/v1.0/directoryRoles/roleTemplateId=88d8e3e3-8f55-4a1e-953a-9b9898b8876b/members/$ref
Content-type: application/json
{
"#odata.id": "https://graph.microsoft.com/v1.0/directoryObjects/UserID"
}
Reference:
Add graph api permission to user account by Harpreet Singh Matharoo

Give App Service enough permissions to link SSL certificate from Key Vault

I have a Bicep template where I create an App Service in which I need to link a SSL certificate that exists in Key Vault (both in same resource group).
The Key Vault has Azure RBAC enabled.
I use the following to Bicep template to link the SSL certificate from Key Vault to the App Service:
resource certEncryption 'Microsoft.Web/certificates#2018-02-01' = {
name: '${resourcePrefix}-cert-encryption'
location: location
properties: {
keyVaultId: resourceId('myResourceGroup', 'Microsoft.KeyVault/vaults', keyVaultName)
keyVaultSecretName: '${resourcePrefix}-cert-encryption'
serverFarmId: hostingPlan.id
password: 'SecretPassword'
}
dependsOn: [
webApi
]
}
But it fails with the following message:
The service does not have access to '/subscriptions/3449f-xxxx/resourcegroups/rgabptrialt/providers/microsoft.keyvault/vaults/my-test-vault' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.
This isn't really telling a lot...
What permission do I need to grant exactly? And to what? And where and how do I even grant these permissions?
Do I have to create a Managed Identity and link that in my App Service? And what Permissions/Roles do I need exactly? Or do I need to do something else to make this work?
I couldn't really find any good info on how to do this.
Give App Service enough permissions to link SSL certificate from Key Vault:
I've imported a self-signed certificate (.pfx) in keyvault -> secrets to authenticate.
To resolve,
The service does not have access to '/subscriptions/3449f-xxxx/resourcegroups/rgabptrialt/providers/microsoft.keyvault/vaults/my-test-vault' Key Vault. Please make sure that you have granted necessary permissions to the service to perform the request operation.
I tried in my environment by referring few steps from this article detailed by #Anuraj and modified accordingly to achieve the expected results.
Step-1: Setting up a Key Vault access policy:
Create a key vault from the portal and Goto Access Policies.
Now creating an access policy to link the ssl certificate by configuring a template as per your requirement.
I've selected key,secret & certificate management to enable the permissions as shown:
Search for the "Name/objectID/AppID" for the respective service principal as keyvault has RBAC enabled.
Note: Register an app under AzureAD -> App registrations if needed.
Review all the permissions and create an access policy:
Step-2: Under App Service -> Web Application -> Certificates, I've added the keyvault certificate ( self-signed certificate (.pfx) in keyvault -> secrets).
1.
2.
3.
Bind the SSL certificate by adding TLS/SSL settings and importing the key vault certificate when it has been added to key vault (.pfx).
Note: Make sure the certificate is in .pfx format to avoid any conflicts.
And I ran below script and deployment got succeeded without any permission blockers.
resource certEncryption 'Microsoft.Web/certificates#2018-02-01' = {
name: 'xcc-cert-encryption'
location: 'EastUS'
properties: {
keyVaultId: '/subscriptions/<subscriptionID>/resourceGroups/xxxxRG/providers/Microsoft.KeyVault/vaults/xxxxxkeyvaults'
keyVaultSecretName: 'jahnss'
password: 'xxxxx' //Certificate protected password
extensionResourceId: '/subscriptions/<subscriptionID>/resourceGroups/xxxxRG/providers/Microsoft.Web/serverfarms/xxxxxappserviceplan'
}
}
Output:
I think yes first you need to give permission in key vault
Ensure that the service principal has all the permissions. The only thing that worked for me though is adding the service principal 24681998-555f-4570-a559-2fced2d7e841 which shows up as Microsoft.Azure.WebSites. You can add this through the portal, by adding an access policy for Microsoft.Azure.WebSites or through arm with the GUID.
I added the following principal to the Key Vault access policies: Microsoft Azure App Service (object id: your object id). Permission to get secrets is enough.
By performing similar the steps mentioned in the below answer
How to access key vault from azure app service
Please let me know if you have any doubts or question. Even if you are facing any issues.

Microsoft Azure OAuth Client Credentials Token gets "AuthorizationFailed" response

I want create APIM subscriptions through rest api, And was able to do it successfully by following this Microsoft doc, https://learn.microsoft.com/en-us/rest/api/apimanagement/current-ga/subscription.
And for Authentication I am generating a bearer token using ROPC grant type(My UserName & Password). Everything works fine with this flow.
But i dont want to configure my username & password in a application to get a bearer token, instead i followed Client-Credentials grant type(get token by client id & secret), i am able to generate token, but when i use that token to create subscription in APIM, i am getting a exception
The client '0--e' with object id '0--e' does not have authorization to perform action 'Microsoft.ApiManagement/service/subscriptions/write'
Is it possible to add a AAD application inside APIM AccessControl(IAM) to grant permission.
Or is this any other way to do this? or ROPC is the only way?
Can someone please help.
Yes, you can grant permission to AAD application (service principal) in APIM Access Control (IAM) by assigning it API Management Service Contributor role.
I tried to reproduce the same in my environment and got the below results:
I have generated one access token using Client-Credentials grant type like below:
When I used the above token to create APIM subscription with below query, I got the same error:
PUT https://management.azure.com/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ApiManagement/service/apimService1/subscriptions/testsub?api-version=2021-12-01
{
"properties": {
"ownerId": "/subscriptions/subid/resourceGroups/rgname/providers/Microsoft.ApiManagement/service/servicename/users/xxxxxxxxxxx",
"scope": "/subscriptions/subid/resourceGroups/rgname/providers/Microsoft.ApiManagement/service/servicename/products/xxxxxxxxxxx",
"displayName": "testsub"
}
}
Response:
To resolve the error, you need to grant API Management Service Contributor role for that application like below:
Go to Azure Portal -> APIM Services -> Your APIM -> Access control (IAM) -> Add role assignment
After granting the above role, I generated the access token again and ran the same query as below:
PUT https://management.azure.com/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.ApiManagement/service/apimService1/subscriptions/testsub?api-version=2021-12-01
Response:
When I checked the Portal, APIM subscription got created successfully like below:
Reference:
How to use Role-Based Access Control in Azure API Management | Microsoft Docs

Use a certificate in the keyvault to access multi-tenant application in other tenant

We have a multi-tenant application in our Azure AD tenant. It is authorized in some other tenants (we know which ones). And it has multiple certificates registered to it to be used as client credentials.
We want to remove the certificates from the local stores and use a certificate in the key vault to request a token for one of the external tenant. According to the documentation this is one of the use cases.
Our tenant (id: xxxx):
Has app registration (app id: abcd-xxx-xxxx-xxx)
has keyvault
has managed service principal (with access to the key vault)
other tenant (id: yyyy):
Executed Admin consent for our application.
Question 1:
How do I create a certificate in the Key vault that is connected to an existing application (app id: abcd-xxx-xxxx-xxx)? It is important to note that since the application is already approved by several third party admins, it cannot be recreated. Same counts for creating a new certificate after it would be expired.
Question 2:
How to I setup the Microsoft.Azure.Services.AppAuthentication library to:
Use the managed identity to access the key vault in our tenant (xxxx).
Use the certificate in the key vault to request a token for our app (abcd-xxx-xxxx-xxx) in other companies tenant (yyyy)
Answer 1:
You could use az ad sp credential reset command like below. If you don't want to overwrite the existing certificate of the App, please pass the --append parameter.
az ad sp credential reset --name '<application-id>' --keyvault joykeyvault --cert cer136 --create-cert --append
Answer 2:
1.To use the MSI access the keyvault in your tenant, just use the code below.
No code changes are required, when you run your code on an Azure App Service or an Azure VM with a managed identity enabled, the library automatically uses the managed identity, see this link.
The environment variable AzureServicesAuthConnectionString has to be set to any credential with access to the keyvault. RunAs=Developer; DeveloperTool=AzureCli for dev or RunAs=App; for managed service identity (automatically in azure).
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Azure.KeyVault;
// Instantiate a new KeyVaultClient object, with an access token to Key Vault
var azureServiceTokenProvider1 = new AzureServiceTokenProvider();
var kv = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider1.KeyVaultTokenCallback));
2.If you want to use the service principal along with its certificate stored in the keyvault to get the token for the resources in another tenant, the connection string on the AzureServiceTokenProvider has to be set to RunAs=App;AppId={TestAppId};KeyVaultCertificateSecretIdentifier={KeyVaultCertificateSecretIdentifier} then you can get tokens for other tenants like.
const string appWithCertConnection = "RunAs=App;AppId={TestAppId};KeyVaultCertificateSecretIdentifier=https://myKeyVault.vault.azure.net/secrets/myCert";
Then use the code to get the token, e.g. for the resource https://management.azure.com/.
var azureServiceTokenProvider2 = new AzureServiceTokenProvider(appWithCertConnection);
string accessToken = await azureServiceTokenProvider2.GetAccessTokenAsync("https://management.azure.com/", "tenant-id-of-thridh-party-tenant").ConfigureAwait(false);

Key Vault 403 during getting access via MSI token

I need to get an access token from my keyvault via MSI.
I follow the guide to enable MSI. MSI is enabled and the necessary
extension was installed.
I perform this guide to add access control of Key Vault for my VM. VM is contributor of KeyVault
I try to get AC according to this guide and gets 403 when I try to get access to the Key Vault.
Step 3 in details:
curl http://localhost:50342/oauth2/token --data "resource=https://vault.azure.net" -H Metadata:true
curl https://<YOUR-KEY-VAULT-URL>/secrets/<secret-name>?api-version=2016-10-01 -H "Authorization: Bearer <ACCESS TOKEN>"
When I run step 2 I get 403 error.
I tried to replace 'https://vault.azure.net' to 'https://' but I got another error:
{"error":"invalid_resource","error_description":"AADSTS50001: The application named https://<YOUR-KEY-VAULT-URL> was not found in the tenant named <A tenant ID>.This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: 7365f8f5-791f-4131-88f8-9466cadc4d00\r\nCorrelation ID: e18e0e5e-966e-460b-9b61-16decf97dff4\r\nTimestamp: 2017-12-12 11:18:01Z","error_codes":[50001],"timestamp":"2017-12-12 11:18:01Z","trace_id":"7365f8f5-791f-4131-88f8-9466cadc4d00","correlation_id":"e18e0e5e-966e-460b-9b61-16decf97dff4"}
What's wrong?
You have to add the VM service principal in Key Vault's Policies. Having Contributor on the Key Vault allows the principal to perform operations through the ARM API, but what it needs to access is the Key Vault API. That requires you to add the principal some permissions on the Policies tab.

Resources