I need help accessing an Azure KeyVault via Service Principal. I currently have two subscriptions that need to communicate and access the other subscription's Key Vault but in order to do so I would need the connection to occur via SPN. I have looked at the documentation for Get-AzureRmKeyVault and it provides no way to authenticate via a SPN from what I can find.
If anyone has a solution I would greatly appreciate it!
Not sure what actually do you mean access keyvault, in azure keyvault, there are Management plane and Data plane, they use different access control mechanisms.
If you want your service principal to do Management plane operations(e.g. set the tag of your keyvault), you need to give it a role in Access control (IAM) of your keyvault in the portal. If you want to do Data plane operations(e.g. operate on the keys, secrets, certificates in the keyvault), you need to add your service principal with correct permissions to the Access policies of the keyvault.
For more details about access control of keyvault, you could check - Secure access to a key vault.
So make sure your service principal already had the correct permission, then use the command below.
$azureAplicationId ="<application-id>"
$azureTenantId= "<tenant-id>"
$azurePassword = ConvertTo-SecureString "<client-secret>" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
Then you can do the Management plane operations like Update-AzKeyVault, or the Data plane operations like Get-AzKeyVaultSecret.
To access the keyvault in a different subscription, just use the command below to select subscription.
Set-AzContext -Subscription <subscription-id>
And I notice seems you are using the old AzureRm module, it was deprecated and will not be updated anymore, I recommend you to use the new Az module, follow Migrate Azure PowerShell from AzureRM to Az.
Related
I have code where i'm trying to get the azurevaultsecret and keep that secrete in one variable. while running the code i am getting forbidden error. Please share the valuable solution.
$ssAADKey = ConvertTo-SecureString $AADKey -AsPlainText -Force
$psCredential = New-Object System.Management.Automation.PSCredential($AADAppID, $ssAADKey)
Connect-AzureRmAccount -ServicePrincipal -Credential $psCredential -TenantId $TenantId
$myApp = Get-AzureADApplication -Filter "DisplayName eq '$($AppName)'" -ErrorAction SilentlyContinue
$Secrets = Get-AzureKeyVaultSecret -VaultName "TestVault1" -name "TestSecret1" -ErrorAction Stop
$password =$Secrets.SecretValueText
I test with your code in my site and it works well.
According to your description and error message you provided, I assume that you may not give full permision to your Azure Key Vault. You could refer to the following steps to troubleshoot.
1.Add a new app registration in Azure AD. Then we can get tenantId, appId, secretKey from the Azure Portal, please refer to this article.
2.Add permission with "Key Vault" to the registered app.
3.In Key vault channel, you need to Add policies to your registered application or user. And in Access Control you need to add permission to your registered application or user.
For more details, you could refer to this SO thread.
One more recent cause of the 'Forbidden' error is that you've enabled the Firewalls and virtual networks feature, and haven't enabled the "Allow trusted Microsoft services to bypass this firewall?" option which can be found here:
Log into the Azure Portal
Navigate to your Key Vault
From Settings, select Firewalls and virtual networks
Scroll down to the section entitled Exception
Make sure your Azure CLI /Client public IP is allowed Key Vault Network Firewall access to the key vault in question (Azure Key Vault; Networking; Firewall; IPv4 address or CIDR) in addition to having permission to update/modifying the key vault.
Determine your CLI public IP by use:
(Invoke-WebRequest -Uri https://myexternalip.com/raw -UseBasicParsing).Content
I am using below Azure Powershell command in VSTS.
(Get-AzureKeyVaultSecret -vaultName "debugkv" -name "CoreConfig-StorageAccount-AccessKey")
I am getting ##[error]Access denied error while running it in VSTS but loclaly it works fine.
I have added the SPN in KV's access policies also with GET and SET permissions for secrets.
Need help in troubleshooting it.
To link VSTS to you need to give the Service Principal, which forms the Service Endpoint in VSTS, access to the Key Vault; you already know this.
What can be confusing is that you can assign the application and the service principal to have access to the key vault depending on your use case. Therefore, you must ensure that you assign the right object to the access policy.
The best way to ensure you assign the right object is to do it through Azure Powershell.
Running a signed in Azure Powershell session:
$spObjectId = Get-AzureRmAdServicePrincipal -SearchString <ServicePrincipalName> | Foreach-Object {$_.Id}
Set-AzureRmKeyVaultAccessPolicy -VaultName <VaultName> -ObjectId $spObjectId -PermissionsToSecrets Get,Set
If you wanted to see further details (objectids, permissions etc) of the access policies you can get these through Powershell also:
Get-AzureRmKeyVault -VaultName <VaultName> | Foreach-Object {$_.AccessPolicies}
I have a Azure Key Vault in which I want to add access policies for my MSI enabled App Service using powershell.
Using portal it's straightforward. As you can see below, I am searching by my app service name and I see app service and app registrations both.
in above example I selected app service directly without registrating it in Azure AD and it's working awesome.
I just need guidance to do the same using Azure Powershell(which will run VSTS SPN).
Please help.
Thanks
Set-AzureRmKeyVaultAccessPolicy -VaultName $valutName -UserPrincipalName 'PattiFuller#contoso.com' -PermissionsToKeys create,import,delete,list -PermissionsToSecrets set,delete -PassThru
Make sure you have logged in from the PowerShell and selected the resource group where the resource exists before you run the command.
Refer documentation for more.
You need to use the the Set-AzureRmKeyVaultAccessPolicy command but with ObjectId parameter.
Set-AzureRmKeyVaultAccessPolicy -VaultName my-keyvault -ResourceGroupName my-resource-group -ObjectId 15faf32d-146a-4985-a315-640527b6c489 -PermissionsToSecrets get
Bear in mind that MSI apps are registered as Enterprise Apps.
EDIT: Curious, what are you trying to achieve?
I have this Azure Powershell script, which successfully backs up a SQL Azure DB to Azure Blob.
In its current form, it requires me to log in via AD.
I now need to implement this script to execute via a Azure Function at specific intervals.
The first snippet of the script:
$subscriptionId = "YOUR AZURE SUBSCRIPTION ID"
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId $subscriptionId
I thus need to not use Login-AzureRmAccount, but replace it with a method that does not require human input.
I have found this link:
https://cmatskas.com/automate-login-for-azure-powershell-scripts/
In short, the author:
Creates an Azure AD Application (with its own password)
Creates a Service Principal
Assigns Permissions to the Service Principal
This is a once-off manual creation - which is perfect.
The author then logs in to this newly created application
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Add-AzureRmAccount -Credential $psCred -TenantId e801a3ad-3690-4aa0-a142-1d77cb360b07 -ServicePrincipal
My questions:
Is this what I should do to be able to automate my application and prevent human login?
This Azure AD app created in step 1 - can I use this app as a starting point in my of my Azure functions?
Yes, you can use that route, or use certificate auth, or use an Azure AD user, it can login with user\password, but is considered less secure than service principal.
Yes, you can use one service principal for any number of Azure Functions you would like to.
To use Azure PowerShell in Azure Functions, you may refer to the following response in another SO thread. The example is an HTTP-Trigger, but you can modify it to use a Timer-Trigger for your use-case. Here's the link:
Azure Function role like permissions to Stop Azure Virtual Machines
Run PowerShell as Administrator, you need to install AzureRM in PowerShell,
Login to Azure
Login-AzureRmAccount
Enter your Azure credentials
To get your subscription(s) details
enter
Get-AzureRmSubscription
Use the subscription id to select the subscription.
Select-AzureRmSubscription -SubscriptionId xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Save the AzureProfile using the below command
Save-AzureRmProfile -Path "C:\AzureScripts\profile.json"
The json file can be used to login to Azure
Select-AzureRmProfile -Path "C:\AzureScripts\profile.json"
Put this line on top of you .ps1 file, you does not require human input.
Ref : http://www.smartcoding.in/blog/auto-login-azure-power-shell
I can't find any documentation on how to choose which AAD to create the service principal in. Basically, I can't find out if there is even a way to add the SP to the local AAD.
So we have a default Global AD which covers all of our enrollment and below that all subscriptions. I'm using Powershell derived from the many many examples on the net to create a SP in the default AD. Then I permission that SP against the subscription it is going to be working in.
At this point I've run into the following problem.
I'm rolling out a Key Vault, this works.
New-AzureRmKeyVault -VaultName $VaultName -EnabledForDeployment -EnabledForTemplateDeployment -ResourceGroupName $ResourceGroupName -Location $Location -Verbose
I need to add the first secret into it as part of the deployment. This bit fails because the SP doesn't have access to the KV.
# Set-AzureRmKeyVaultAccessPolicy -VaultName $VaultName -ResourceGroupName $ResourceGroupName -PermissionsToSecrets get,set -ServicePrincipalName $ServicePrincipalName
This is the result of that command.
Set-AzureRmKeyVaultAccessPolicy : Cannot find the Active Directory object
'Service-Principal-Name' in tenant '6166a717-xxxx-xxxxx-b0e8-6b7288c1f7ec'.
Please make sure that the user or application service principal you are
authorizing is registered in the current subscription's Azure Active
directory.
Reading into this, its not possible to set the Global AD Service Principal to have get/set on the local Keyvault. it would have to be a local Service Principal. However, we dont have one of them and nowhere can I work out how to create one of them.
Anyone else feeling this pain and know how to resolve it?
In the settings section of the old portal (manage.windowsazure.com), you will find a list of all subscriptions. The fourth column (Directory) shows the default directory that is associated with each subscription. No matter what, you will have to create the Service Principal in the Directory that is associated with that particular subscription. Please check this link to understand the relationship between Subscriptions and AAD.