In Kuberentes secret, required format is:
apiVersion: v1
kind: Secret
metadata:
name: azcreds
type: Opaque
stringData: # use `stringData` for raw credential string or `data` for base64 encoded string
AZ_CLIENT_ID: xxxxx
AZ_CLIENT_SECRET: xxxxx
AZ_SUBSCRIPTION_ID: xxxxx
AZ_TENANT_ID: xxxxx
How do i get these credentials? I have a Storage account, and when I go to Access keys I only see Key and ConnectionString
Firstly, you need to Login to Azure Portal
Then open Azure Active Directory
Then Click on App Registrations
Then Click on your owned application
Then Click on your application, You will find the credentials as below:
To find the Client secret you need to Click on App registrations the click on Certificates and Secrets then you will find your Secret as below:
Your secret template seems to refer to Azure AD Application Registrations.
You need to create a new App Registration and assign the required permissions on the storage account (e.g. Blob Storage Contributor)
https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-portal?tabs=current
Related
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.
My Azure PaaS service supports authenticating directly with OAUTH (Event Hub).
How do you distribute the credentials for this securely to Confidential Clients?
Sorry i'm new to Cloud Development.
As you mentioned, you can use Azure keyvault to store the client secret of your Azure AD App Registration.
Just add the client app/user account to the Azure keyvault Access Policy with the correct permission, then only them can access your azure keyvault to retrieve the client secret.
Update:
You need to create a new Azure AD App Registration used to access the keyvault(this AD App is just to access keyvault, not access to eventhub), store its client id and secret as the environment variables, then use the SDK to get the secret. After that, use ClientSecretCredential to access eventhub.
TokenCredential credential = new ClientSecretCredential("<tenantId>", "<clientId>", "<clientSecret>");
var fullyQualifiedNamespace = "<< FULLY-QUALIFIED EVENT HUBS NAMESPACE (like something.servicebus.windows.net) >>";
var eventHubName = "<< NAME OF THE EVENT HUB >>";
await using (var producer = new EventHubProducerClient(fullyQualifiedNamespace, eventHubName, credential))
{
using EventDataBatch eventBatch = await producer.CreateBatchAsync();
eventBatch.TryAdd(new EventData(new BinaryData("First")));
eventBatch.TryAdd(new EventData(new BinaryData("Second")));
await producer.SendAsync(eventBatch);
}
Reference - Using an Active Directory principal with the Event Hub clients
Note: Actually, if your code will be deployed to the Azure service that supports Managed Identity(MSI), e.g. Azure App service, VM, etc, the best practice is to use MSI to auth eventhub, no need to create the AD Apps and use their client secrets, neither the keyvault.
Reference - Authenticate a managed identity with Azure Active Directory to access Event Hubs Resources
Can I provide my own client secret either from the portal or via command line - while adding a New Client Secret?
It is possible, If you want to create a new client secret just use the --append parameter with az ad app credential reset
az ad app credential reset --id "<application id or object id>" --password "stackoverflowrocks!"
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);
I would like to use an Azure Key Vault secret from an on-premise web application.
I created a Key Vault with a Secret, but in Access Policies I should specify an Authorized Application and in the samples is used an Azure WebApp.
I want instead use the Secret from on-premise MVC web app: shoud i specify nothing and it works ? i specified the Azure Vault and as Principal myself but i'm not sure if this is correct.
Well, something will need to authenticate to access the secret.
Either the current user, or you can use a service principal.
Since we are talking about an MVC app, the service principal is probably easier.
You will need to register a new app in Azure Active Directory via the Azure Portal.
Find Azure AD, and register a new app via App registrations.
The name and URLs don't really matter, but it needs to be of type Web app/API.
The sign-on URL can be https://localhost for example.
Then add a key in the Keys blade to the app (click Settings after the app is created, then Keys).
Copy the client id (application id) and the key somewhere.
Now you can go to your Key Vault, and create a new access policy, and choose the app you created as the principal.
Give it the rights you want, like Secrets -> Get.
Then you can save the policy.
In your app, you can then use the Key Vault library + ADAL like so:
var kvClient = new KeyVaultClient(async (authority, resource, scope) =>
{
var context = new AuthenticationContext(authority);
var credential = new ClientCredential("client-id-here", "key-here");
AuthenticationResult result = await context.AcquireTokenAsync(resource, credential);
return result.AccessToken;
});
SecretBundle secret = await kvClient.GetSecretAsync("https://yourvault.vault.azure.net/", "secret-name");
string secretValue = secret.Value;