Access azure key vault from azure blob storage (static website) - azure

I got a blob storage which I use as website.
This blob has a system assigned managed identity.
This identity is added to a key vault as access policy.
So actually it should be able to access the secrets.
But when I try it the way microsoft documented it I got an error.
const getSecret = async () => {
var credential = new DefaultAzureCredential({
ManagedIdentityClientId: "<blob-id>",
} as DefaultAzureCredentialOptions)
const keyVaultName = "<key-vault-name>"
const url = "https://" + keyVaultName + ".vault.azure.net"
const client = new SecretClient(url, credential)
const secret = await client.getSecret("function-key")
}
I got the error
Error: DefaultAzureCredential is not supported in the browser. Use InteractiveBrowserCredential instead.
at Module.60308 (defaultAzureCredential.browser.js:5:34)
Is this even possible?
Thanks!

Please check this azure-sdk-for-js issue according to which ,
interactive credentials is recommended instead of default
credentials.And for client side applications that run in the browser,
the InteractiveBrowserCredential is the only credential type that is
supported.Please check this github reference
So for interactive credentials for Node.js, if a clientId is
provided, the Azure AD app need to be configured to have a "Mobile and desktop applications" as redirect endpoint instead of web. See
set up redirect uri
See DefaultAzureCredential and examples
Also according to DefaultAzureCredential Class | Microsoft Docs
The following credential types if enabled will be tried, in order:
EnvironmentCredential >ManagedIdentityCredential >
SharedTokenCacheCredential > VisualStudioCredential >
VisualStudioCodeCredential > AzureCliCredential>
AzurePowerShellCredential >InteractiveBrowserCredential: uses browser to auth users - not enabled by default. Pass true to the DefaultAzureCredential to enable it.

Related

How to ask DefaultAzureCredential to use my user credential locally

I'm trying to develop a web app on an Azure VM that uses Azure Key Vault. Later this app will also be deployed to Azure. As far as I know, the most straight forward way to make the app work, both locally and deployed, with the key vault, is to use the DefaultAzureCredential class. The code would be like this:
string kvUri = "https://" + keyvaultName + ".vault.azure.net";
SecretClient client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
KeyVaultSecret secret = await client.GetSecretAsync(secretName);
At runtime, the provider will try different credential types in order.
This sounds exactly what I want:
When developing locally (on the Azure VM, though), I want to use my user credential (user identity added to the key vault's permission) without any configuration, since I have already logged into the Visual Studio using the same user credential.
Once deployed to Azure, I want to use the app registration credential (also added to the key vault's permission).
But when running the app locally, I'm getting a 403 error The user, group or application .... does not have secrets get permission on key vault ...
After looking up the object id in the error message, I realize it's the dev machine Azure VM's credential that the application uses, not my user credential.
Is there a way to change this behavior?
To prevent the Azure VM from getting a token, you can exclude the ManagedIdentityCredential in your Development environment and only enable it in a Non-Development environment.
if (environment.IsDevelopment())
{
var credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
ExcludeManagedIdentityCredential = true,
ExcludeAzureCliCredential = true
});
}
else
{
var credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions
{
ExcludeVisualStudioCodeCredential = true,
ExcludeVisualStudioCredential = true
});
}
Once deployed to Azure, I want to use the app registration credential (also added to the key vault's permission).
An Azure App Service can use a managed identity as well. There is no need for a separate App Registration.
See https://learn.microsoft.com/en-us/dotnet/api/overview/azure/identity-readme#key-concepts for more information.
Create and identity if you wish to use (default identity)
appservice -> select you application -> identity->enable it ->should give you a Id
and than add it to key Vault Access policy
alternatively app registration can be used with tenantId,clientId,secret to connect to keyvault

Api-version must be specified when using azure keyvault SecretClient .net sdk

I am trying to set a secret in azure keyvault using managed identity. There are two problems which I am facing right now. Hope someone can help me with it.
Code:
var client = new SecretClient(new Uri("keyvaulturl"),
new DefaultAzureCredential(new DefaultAzureCredentialOptions()
{ ExcludeManagedIdentityCredential = true }));
await client.SetSecretAsync(new KeyVaultSecret(keyName,
serializer.SerializeObject(someobject)));
Problem 1:
DefaultAzureCrendetialOption is not working for managed identity but when I am setting ExcludeManagedIdentityCredential to true it is able to fallback to the next authentication provider (must be azure cli). I am not sure why this is happening because couple of days before the same code was working and I was able to set and retrieve keyvault secrets using the same code.(ofcourse without using any DefaultAzureCredentialOptions parameters).
Please note this problem only happens in my local env and managed identity works fine when deployed in azure.
Problem 2:
When setting ExcludeManagedIdentityCredential to true for local development, I started seeing another problem where it is giving me error that api-version is missing. I dont understand why and where do I need to specify the api version when using azure .net sdk.
Error:
Service request failed.
Status: 400 (Bad Request)
Content:
{"error":{"code":"BadParameter","message":"api-version must be specified"}}
Problem 1:
Managed Identity cannot be used to authenticate locally-running applications by design. Try to read the Important tip in the document.
Managed Identity cannot be used to authenticate locally-running
applications. Your application must be deployed to an Azure
service that supports Managed Identity.
Problem 2:
Please change the version of Azure Key Vault secret client library with the latest varsion.
dotnet add package Azure.Security.KeyVault.Secrets
I tried DefaultAzureCredential with environment variables in my local.
string keyVaultName = Environment.GetEnvironmentVariable("KEY_VAULT_NAME");
var kvUri = "https://" + keyVaultName + ".vault.azure.net";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
KeyVaultSecret secret = new KeyVaultSecret("testdefault", "123456");
KeyVaultSecret result = await client.SetSecretAsync(secret);
Console.WriteLine(result.Name);

Azur Key Vault - CORS Error after using Azure KeyVault in Azure App Service

I'm trying to get value from Azure Key Vault. It's working well in localhost but when we deploy to Azure App Service. it shows CORS Error:
Access to XMLHttpRequest at 'https://xxxxxxxx.azure-api.net/xxxxxx/api/xxx/xxxx' from origin 'https://xxxxxxx.azurewebsites.net' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm using below code in my .Net Core Web API:
const string secretName = "XXXXXXXXXXXXXX";
var kvUri = $"https://xxxxxxxx.vault.azure.net";
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
var secret = client.GetSecretAsync(secretName).GetAwaiter().GetResult().Value;
conString = secret.Value;
Thanks in advance
CORS isn't permitted for Key Vault at this time because it's not designed to be used by browsers. I spoke with the KV product team about this a good while back and created a UserVoice submission for this feature a few years ago: https://feedback.azure.com/forums/906355-azure-key-vault/suggestions/34753195-enable-cors-for-key-vault
Were you logged in to Azure when you tested this application locally?
Also for app service to access key vault you would need some authentication mechanism
like service principal or managed Identity.
You can check this link for your reference:
Access key vault from app service

Get Secret from Azure Keyvault using nodejs

I need to read the list of users in the Azure active directory. The client has created a Graph API application but they do not want to share the client secret of the application, instead they asked us to use the Key vault. How to access from the node.js application the key to retrieve the list of users?
I tried the below one but gave error and I am not sure how to authenticate.
const { DefaultAzureCredential } = require("#azure/identity");
const { SecretClient } = require("#azure/keyvault-secrets");
const credential = new DefaultAzureCredential();
const vaultName = "lsm-keyvault";
const url = `https://${vaultName}.vault.azure.net`;
const client = new SecretClient(url, credential);
const secretName = "Demo";
async function main() {
const result = await client.setSecret(secretName, "MySecretValue", {
enabled: false
});
console.log(result)
}
Well, if you run the code in local, the DefaultAzureCredential will use the environmental variables automatically.
So in your case, you need to register an application with Azure AD, and get the tenant id, client id(i.e. application id), client secret(i.e. application secret), set the environmental variables, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID.
For the 403 error you got, I notice you said It added as a compound entity, based on my experience, you did not add the correct service principal related to the AD App correctly to the Access policies of the keyvault. If you add it correctly, it will appear as APPLICATION, not COMPOUND IDENTITY.
So when you add it, you could search for the client Id(i.e. application Id) or the name of your App Registration directly, make sure you add the correct one. I gave the details in this similar issue, you could refer to it.
To retrieve the secret, the Get permission is enough, the code should be
const retrievedSecret = await client.getSecret(secretName);
I notice you use client.setSecret in your code, it is used to save a secret, to use it, you may need the Set permission.
For more details, see Quickstart: Azure Key Vault client library for Node.js (v4).
Update:
I have to eventually need to deploy this but not in azure but in another environment. How do I set the environment variables and access it.
If so, you need to change your code to authenticate, use the three values directly in the code.
Change the lines
const { DefaultAzureCredential } = require("#azure/identity");
const credential = new DefaultAzureCredential();
To
const { ClientSecretCredential } = require("#azure/identity");
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
See - https://www.npmjs.com/package/#azure/identity/v/1.0.3#authenticating-as-a-service-principal
All you need to do is follow the below steps:
Create an App in the Azure Active Directory (Service Principal) from App Registrations.
Go to Key Vault resource, Access Policy blade, assign read access to this Azure AD App (Service Principal) that we created in the above step.
Set these 3 Environment variables AZURE_CLIENT_ID, AZURE_TENANT_ID, and AZURE_CLIENT_SECRET in your App Service. Get the values of these variables from the app that we created in step 1.
Use DefaultAzureCredential that we are already using now. This will automatically pick the credentials from the environment variables that we defined in App Service for the authentication.
Another way is to obtain Key Vault token dynamically and use that token to get the secrets from the Key Vault - https://learn.microsoft.com/en-us/samples/azure-samples/app-service-msi-keyvault-node/app-service-msi-keyvault-node/
Helpful Reference:
https://www.rahulpnath.com/blog/defaultazurecredential_from_azure_sdk/

Retrieve Azure KeyVault secret using client secret

I'm experimenting with various Azure features and currently want to retrieve a secret from KeyVault.
Straight to the case:
I'm using this nuget package to interact with my azure resources.
I've developed a simple .NET Core console app and run it locally.
I have a KeyVault resource with one secret defined which is active and not expired.
I've registered an App in AAD so my locally shipped .NET Core console app has an identity within AAD.
Than I've created a "client secret" within this registered app in AAD to use it to authenticate myself as an app.
After that I've added access policy in my KeyVault resource to allow GET operation for secrets for this registered app:
Then I've developed a small piece of code which should retrieve the desired secret:
public class AzureAuthentication
{
public async Task<string> GetAdminPasswordFromKeyVault()
{
const string clientId = "--my-client-id--";
const string tenantId = "--my-tenant-id--";
const string clientSecret = "--my-client-secret--";
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var client = new SecretClient(new Uri("https://mykeyvaultresource.vault.azure.net"), credentials);
var secret = await client.GetSecretAsync("admincreds");
return secret.Value.Value;
}
}
However when I'm trying to do this I'm getting an AccessDenied error:
Am I missing something painfully obvious here? Or there is some latency (>30 min for this moment) for which changes from Access policies screen in KeyVault resource are applied?
I test your code and Get permission, it works fine.
From your screenshot, it looks you didn't add the correct service principal related to the AD App to the Access policies.
If you add the service principal related to the AD App, it will appear as APPLICATION, not COMPOUND IDENTITY.
So when you add it, you could search for the client Id(i.e. application Id) or the name of your App Registration directly, make sure you add the correct one.
Make sure your AD App(service principal) has the correct permission in your keyvault -> Access policies

Resources