Key Vault 403 during getting access via MSI token - azure

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.

Related

Azure Application Access Only Key Vault Keys

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:

How can I grant consent to my own app in azure, in case I am not global admin in tenant?

Given I have created an app using this repository in Azure.
And this app is deployed using a Service Principal which was created by below command:
az ad sp create-for-rbac --name "fxpricepredictor" --role contributor --scopes "/subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/YOUR-RESOURCE-GROUP-NAME" --sdk-auth
Now, I need to get the API token to manage my created resources using REST APIs.
Based on documentation, I should be able use my tenantId, clientId and client_secret to get the token by calling the bellow endpoint:
curl: POST
https://login.microsoftonline.com/{{tenantId}}/oauth2/token
Please notice that, I am not the global admin in the tenant.
The official sample postman collection is here and here is how my request looks like in postman:
Sadly the endpoint does not provide me the token and instead it returns such error:
{
"error": "unauthorized_client",
"error_description": "AADSTS700016: Application with identifier 'MY_CLIENTID' was not found in the directory 'MY COMPANY'. 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 may have sent your authentication request to the wrong tenant.\r\nTrace ID: 5a9a2c53-c3c8-46da-a1a6-551b42082400\r\nCorrelation ID: bf7c5966-ffa4-4312-8a77-434c2560d65a\r\nTimestamp: 2022-10-05 14:54:23Z",
"error_codes": [
700016
],
"timestamp": "2022-10-05 14:54:23Z",
"trace_id": "5a9a2c53-c3c8-46da-a1a6-551b42082400",
"correlation_id": "bf7c5966-ffa4-4312-8a77-434c2560d65a",
"error_uri": "https://login.microsoftonline.com/error?code=700016"
}
please notice, I hided some sensitive values in error response by MY_CLIENTID and MY COMPANY
So, i guess, the main reason that i am facing this issue is that:
This can happen if the application has not been consented to by any user in the tenant.
Meaning that, i should consent my own app. Am I right ?
So, my question is:
How can i get the token to work with REST APIs to manage my resources ?
How can I grant consent to my own app, given that I am not a global Admin ?
Update:
As I figured out, I should be able to Grant Consent to my app using "Microsoft Graph permissions reference". And here is what i have done:
Login to Azure portal
Navigate to "Azure Active Directory"
Navigate to "App registrations"
Click on the created APP ("fxpricepredictor")
Navigate to "API permissions"
Click "Add a permission"
Click on "Microsoft Graph"
Choose "Delegated Permissions"
Search for "authentication" ---> (Sadly this option also requiereds Admin Consent)
I tried to reproduce the same in my environment and got the below results:
When I ran the same command as you, one Azure AD application named fxpricepredictor is automatically created with details like below:
az ad sp create-for-rbac --name "fxpricepredictor" --role contributor --scopes "/subscriptions/<subscriptionID>/resourceGroups/<resourcegroupName>" --sdk-auth
By including above details as parameters, I am able to generate access token successfully via Postman like below:
Please note that, I don't have global administrator role and granting admin_consent is not really required.
With the above access token, I am able to fetch and manage the Azure resources in that resource group like below:
GET https://management.azure.com/subscriptions/<subscriptionID>/resourceGroups/SriTest/resources?api-version=2021-04-01
Response:
The error AADSTS700016 may also occur if there is no application in your tenant with provided ClientID.
I tried including random ClientID which does not exist in Azure AD tenant and got same error as below:
So, make sure to check whether the application is existing or not with the given ClientID in Azure AD tenant.

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

Can't get access token for custom AD Application

When attempting to get an access token for a custom AD Application, using az account get-access-token --resource '<APP ID Uri>', I receive the following error:
AADSTS65001: The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Microsoft Azure CLI'. Send an interactive authorization request for this user and resource.
04b07795-8ddb-461a-bbee-02f9e1bf7b46 is not my application id, and my application has had administrator consent granted. I've tried putting this id in an interactive login request with no change in behavior.
get-access-token works fine when the resource is a defined MS endpoint like https://database.windows.net or https://vault.azure.net/
My goal is to have Azure App Services with Managed Service Identity authenticating to each other with short-lived AD bearer tokens. Each service has a configured audience that corresponds to the AD App.
Running az account get-access-token --resource '<APP ID Uri>' from local CLI, you are trying to get token from '<APP ID Uri>' using Azure CLI, which client ID is exactly 04b07795-8ddb-461a-bbee-02f9e1bf7b46.
To handle this you could go to:
Azure Active Directory → App registrations → {your app} → Expose an API → Add client application with:
ID: 04b07795-8ddb-461a-bbee-02f9e1bf7b46
Authorized scopes: check '<APP ID Uri>'
To make sure you have right ID you could run az account get-access-token paste token to jwt.io and find value of "appid".
Documentation reference:
Application IDs for commonly used Microsoft applications
I can reproduce your issue with a --resource '<APP ID Uri>', if I login cli with a user account.
If I login with a service principal, it works fine.
You could try to login azure cli with a service principal, refer to this link.

Obtaining an access token for MSI enabled web application

I have a Web API project hosted in Azure as web app with Managed Service identity enabled (so I don't need an app registration, right?):
Now I need to obtain a token to access my API so that I can use it in POSTMAN:
az login
az account get-access-token --resource "https://mytenant.onmicrosoft.com/d3a219e0-bbbf-496b-a4a4-b9ca485c5a52"
which gives me
Get Token request returned http error: 400
and server response:
{"error":"invalid_resource","error_description":"AADSTS50001: The
application named
https://mytenant.onmicrosoft.com/d3a219e0-bbbf-496b-a4a4-b9ca485c5a52
was not found in the tenant named
xxxxxxxx-xxxx-xxxx-af31-xxxxxxxxxx. 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.
I get the same error if I try to use object id 63d571cf-79bf-405d-8304-a31fb64cb953 instead of app id as part of resource uri.
What am I doing wrong?
What am I doing wrong?
az account get-access-token is used to get token to access the Azure resource. We could get more information from this document.
--resource
Azure resource endpoints. Default to Azure Resource Manager Use 'az cloud show' command for other Azure resources.
The resoure should be in the following endpoints. And default resource is https://management.azure.com/
"endpoints": {
"activeDirectory": "https://login.microsoftonline.com",
"activeDirectoryDataLakeResourceId": "https://datalake.azure.net/",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"activeDirectoryResourceId": "https://management.core.windows.net/",
"batchResourceId": "https://batch.core.windows.net/",
"gallery": "https://gallery.azure.com/",
"management": "https://management.core.windows.net/",
"resourceManager": "https://management.azure.com/",
"sqlManagement": "https://management.core.windows.net:8443/",
"vmImageAliasDoc": "https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/arm-compute/quickstart-templates/aliases.json"
}
Based on my understanding, the command no relationship with your API access.
For more information about MSI and how to protect an API by using OAuth 2.0 with Azure Active Directory, please refer to this tutorial and this tutorial.
The resource URI does not contain your Application Id nor Object Id.
It is a separate identifier that you can find from the App Registration's Properties under App ID URI.
And since this is an MSI-generated service principal, there is no app. I think you have to register an app in this case.

Resources