Get secrets in Azure Key vault from api management? - azure

I've created a vault in Azure and gave it access to API management (registered app in AAD). I'm trying to not store any passwords in header while making API calls, but instead get them from the keyvault. Is there a way to do this? If yes how?
Been looking for days and haven't found something
Thanks

You need to use API Management Policy to get the job done (https://learn.microsoft.com/en-us/azure/api-management/api-management-policies).
The policy needs to be constructed to post HTTP request to Azure AD OAuth endpoint to receive access token (https://learn.microsoft.com/en-us/azure/api-management/api-management-transformation-policies#TransformationPolicies). Using access token you just need to call to Key Vault API and retrieve the secret (https://learn.microsoft.com/en-us/azure/api-management/api-management-advanced-policies#SendRequest). That secret will be passed along in your header (set-header)
Sample to get access token: https://learn.microsoft.com/en-us/azure/api-management/policies/use-oauth2-for-authorization?toc=api-management/toc.json

Here is an end to end example of Azure API Management and Azure Key Vault, including how to setup authorization in Azure AD so APIM can read secrets, certificates, etc. from Key Vault.
https://github.com/kevinhillinger/azure-api-management-keyvault
The integration requires that a service principal is registered in the Azure AD tenant for the subscription that the Key Vault instance belongs to. Then we're going to authorize it to talk to key vault.
In the example provided, I am retrieving a certificate since this is the more "difficult" option.
Here is the flow for the integration of Azure Key Vault:
Get a minted token (bearer) from Azure AD (make sure the scope is properly set for Key Vault)
Get the response and set a variable with the token value
Send a request to Key Vault with Authorization header loaded up with the token
Get the certificate info
Fetch the entire PFX file in base64

Related

Azure API Management /Azure function authentication approach?

Confused on which type of authentication method to use for Azure API Management/Azure Functions:
User name & password(saving keys in keyvault)
Token(non expiring/expiring)
Subscription key
IP Filter
Oauth2
If we go with option 5:
Does grant_type,client_id,client_secret and scope are the required keys in order to generate the token? And can we encrypt the values before giving it to vendor?
How can we change the token authorization url from login.microsoftonline.com/tenanted to our dns? Do we need to use azure front door or is there any other option?
There's no unique/right answer based on what you've described. I usually recommend choosing one Identity Provider (IDP) (e.g. Azure AD) + Product Subscription at API Management.
Identity Provider will take care to generate auth token, and your Azure Function or API Management can validate against IDP to guarantee the token is valid and issued by the IDP.
If you'll charge based on API calls, you use the API Management Subscription Key to filter/count and charge properly the consumers of your API. Also, only callers with a valid Subscription Key will be able to consume your API.
Now answering your other two questions:
1-) If you're using Azure AD as IDP, then yes
2-) you can't, unless you'll use your own IdP (e.g. Identity Server)

Get access to Azure Blob storage and Key Vault from Azure ad B2C account

i'm new in Azure. And if the question is stupid don't punish me.
I made an App in Azure to get access to storage blob and key vault.
I used Azure AD tenant(with AD users) and user_impersonation scopes like https://storage.azure.com/user_impersonation and https://vault.azure.net/user_impersonation
All I need from that App is:
Upload file to Blob
Download file from Blob
Delete file from Blob
Generate SAS
Get value of secret from Key Vault.
In Azure AD tenant it works fine. I can request to login.microsoftonline.com enter credentials and get token to my back-end to do all this things listed above.But later customer desided to use custom UX(to hide Microsoft login page) and only one way to get this is to use B2C and local accounts.
I made a B2C tenant like here tutorial-create-tenant
Registered App like here tutorial-register-applications and add Api permissions to Azure Storage from APIs my organization uses tab
Created user-flows like here user-flows
All local users in one group with Owner policy
Using this request i got a token
https:/<domain_name>.b2clogin.com/<domain_name>.onmicrosoft.com/oauth2/v2.0/authorize?
p=B2C_1_signin&
client_id=<App_ID>&
nonce=defaultNonce&
redirect_uri=https%3A%2F%2Fjwt.ms%2F& // https://jwt.ms/
scope=https%3A%2F%2Fstorage.azure.com%2Fuser_impersonation& // https://storage.azure.com/user_impersonation
response_type=token&
prompt=login
In decoded token claim "aud" has id the same as Azure Storage API from APIs my organization uses tab when I register App, "scp" is "user_impersonation". But using this token i can't get access to storage using Postman (I use it as Bearer token)
For example GET request to https://.blob.core.windows.net/?comp=list must return json with list of containers(and in Azure AD it work) but with this token got an error
<Error>
<Code>AuthenticationFailed</Code>
<Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:49873755-401e-0065-0dd0-386211000000
Time:2020-06-02T11:24:57.3079213Z</Message>
<AuthenticationErrorDetail>Signature validation failed. Signature key not found.</AuthenticationErrorDetail>
</Error>
May be I need to add additional Api access to Storage app some how?
What should I set up yet?
Or maybe there is a way to connect Ad B2C tenant to AD tenant?
Will appreciate any help.
Upd: as #juunas noiced I had differernt subscriptions for B2C tenant and Storage account. Now b2c and storage in one sub(i created new b2c, link subscription and move it inside b2c tenant, after that i made a storage account in moved subscription)
But the problem still exist.
I tried to change scope in request. On Api Permissions page in Azure Storage user_impersonation option you can see link like
https://*.dfs.core.windows.net/user_impersonation
when I used this link as a scope I've got an error
AADB2C90117: The scope
'https://*.dfs.core.windows.net/user_impersonation'
provided in the request is not supported.
After replacing of asterisk by name of storage account in link I've got the next message
AADB2C90205: This application does not have sufficient permissions
against this web resource to perform the operation.
It looks like I need to get additional permissions for App?
Does it make sense? Or trying to get access to particular storage account is wrong?

Access azure key vault from Azure Functions dynamically

I am writing a azure functions application in python. It is a http trigger application. The input for the application is userID.
{ "user":"TEST_USER_1" }
The functions should use the username specified in 'user' parameter and look up the password in azure keyvault and attempt a remote login to one of the service. For this, we need to add the application settings parameter for specific keyvault version BUT these changes are static.
For us, all the users and their passwords are added to azure keyvault And we will keep on provisioning more users.
Now, the challenge is how to dynamically access password for any user specified during API call ? Is it possible to access all the secrets in a keyvault without specifying individual secret version?
Here's what you need to do:
create a managed identity for your Azure Function
grant permission on Azure Key Vault (Get / List) for the previous identity
get access token from Azure AD in your function
use the token to retrieve the secret.
Some useful links:
https://learn.microsoft.com/en-us/azure/python/python-sdk-azure-authenticate
https://learn.microsoft.com/en-us/python/api/overview/azure/key-vault?view=azure-python

Authenticate Service Principal with certificate stored in Azure Key Vault

I am trying to authenticate a local hadoop cluster to Azure using a service principal and certificate authentication. I have created a service principal, and put had the key vault create the certificate. I know how to get that information once I am authenticated, but I am trying to figure out how I would re-authenticate automatically once the certificate expires.

A more secure way to use key vault

Usually when you use key vault to encrypt and decrypt data you have to keep your AD registered app's (that has the authorization to access key vault) ClientID and ClientSecret in plain text somewhere. This seems like a security problem if someone steals the the ClientID and Secret anyone can claim they are the registered app.
Is there or can there be a more secure approach?
You can use a certificate to authenticate instead of a secret.
There are three things you need to do for this approach:
Create a certificate to use.
When creating the Active Directory application that you will use to access the Key Vault, you need to pass in the certificate you created in step 1. I don't think you can do this through the portal at the minute, so you'll need to use the New-AzureRMADApplication PowerShell command.
Use that certificate when authenticating to Key Vault. You'll need to use an overload of the AuthenticationContext.AcquireTokenAsync() method that receives a ClientAssertionCertificate to do that. You can create a ClientAssertionCertificate by simply passing the client id and the X509Certificate2.
From this blog post you can get some some code for the first two steps.
In addition to using certificate-based with KeyVault, Azure Managed Service Identity also introduces a new way to make an Azure service become a service principal without any client app registration and client secret. Currently it is only available in preview stage for some services: Azure VM, Azure App Service, Azure Function, Azure Event Hub & Azure Service Bus. More information can be found here https://learn.microsoft.com/en-us/azure/active-directory/msi-overview
[Update] When ever you need to retrieve something from KeyVault, with Azure MSI you don't need a client secret. Only use AzureServiceTokenProvider() method to retrieve access token
In real-world deployment with automation (for example via Ansible), you can use an external certificate to store sensitive variables in Ansibe Vault and generate a 256bit chain to secure such an info. During the automation deployment, the cert is decrypted to access to these variables and perform further deployment. This way adds more encryption layer to the whole Azure deployment.

Resources