Add key vault access policy using power shell does not work - azure

I am calling powershell script to add ADF into key vaults access policies using the following command
If I grant it through portal UI, it works. What could be wrong with the following code or should i use different Api?
$Id = (Get-AzureRmDataFactoryV2 -ResourceGroupName $ResourceGroupName -Name $DataFactoryName).Identity.PrincipalId
Write-Host "Add permissions to key vault"
Set-AzureRmKeyVaultAccessPolicy -VaultName $AKVName -ObjectId $Id -PermissionsToSecrets Get,Set
I get this Error:Set-AzureRmKeyVaultAccessPolicy : 'AccessPolicies' exceeds maximum item count of '16'.
It should add permission to ADF for the given key vault
Thanks

I found my answer in the below post
https://social.msdn.microsoft.com/Forums/azure/en-US/ee3ec74a-3103-4795-92fb-ee5ec5298d38/add-key-vault-access-policy-using-power-shell-does-not-work?forum=AzureKeyVault

Related

How to get only part of Powershell output for Azure key vault?

I have this PS script and I'm trying to get user access information for all Key vaults in an Azure subscription.
So what I'm getting now is all the Key vault information; name, location, ids, different settings, network rules, and then access policies for each user that has some access. Is there a way to strip this output to only get the vault name and access policies?
$resourceGroup = $_
#Gets the key vaults for this resource group
$keyVaults = Get-AzKeyVault -ResourceGroupName $resourceGroup
If ($keyVaults) {
Write-Host 'Resource Group : ' $resourceGroup
write-host "`n"
# Goes through the key vaults for this resource group and shows us the information for each
Foreach ($keyVault in $keyVaults) {
Get-AzKeyVault -VaultName $keyVault.VaultName
write-host "`n"
}
}
}
You can use Select-Object (alias Select) to narrow down your object's returned properties. Property AccessPolicies returns the Tenant ID value associated with each access policy. Property AccessPoliciesText returns the text of the policies.
Get-AzKeyVault -VaultName $keyVault.VaultName | Select VaultName,AccessPolicies
Get-AzKeyVault -VaultName $keyVault.VaultName | Select VaultName,AccessPoliciesText
Note that since you are selecting only two properties, the default formatted output will be table view. The AccessPoliciesText will likely be truncated in table view. You can (for display purposes only) use list format to display all the contents:
Get-AzKeyVault -VaultName $keyVault.VaultName |
Select VaultName,AccessPoliciesText | Format-List
Note that if you plan to store your output into a variable to process later, do not use Format-List until you need to display its value at the console.

Adding key vault access permissions while preserving existing ones

I have an Azure PowerShell task in my pipeline, in which I need to import a certificate to a key vault. Before doing that, I need to assign Import certificate permission to the current service principal. However, this service principal might already have existing certificate permissions (e.g. Get, List) from other tasks in this or other pipelines. If I use Set-AzKeyVaultAccessPolicy, it will remove these other permissions. Is there a way of preserving these permissions, and just adding some new ones?
$spId = (Get-AzContext).Account.Id;
Set-AzKeyVaultAccessPolicy -VaultName $kv -ServicePrincipalName $spId -PermissionsToCertificates Import
Import-AzKeyVaultCertificate -VaultName $kv …
There is no direct way to add the new permission, your option is to get the old permissions as a list, add the new permission to it, then set all the permissions again.
The sample works for me:
$spId = (Get-AzContext).Account.Id
$objectid = (Get-AzADServicePrincipal -ApplicationId $spId).Id
$kv = Get-AzKeyVault -ResourceGroupName <group-name> -VaultName joykeyvault
$cerpermission = ($kv.AccessPolicies | Where-Object {$_.ObjectId -eq $objectid}).PermissionsToCertificates
$cerpermission += "Import"
Set-AzKeyVaultAccessPolicy -VaultName joykeyvault -ObjectId $objectid -BypassObjectIdValidation -PermissionsToCertificates $cerpermission
Note: The parameters in the last line is important, if your service principal used in the devops service connection does not have the permission to list service principals in your AAD tenant, please use -ObjectId $objectid -BypassObjectIdValidation instead of -ServicePrincipalName $spId, otherwise you will get an error.

Azure Keyvault 'unknown' access policy

I added two accounts through powershell from devops yaml pipeline:
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $obj1 -PermissionsToSecrets Set,Get -BypassObjectIdValidation
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $obj2 -PermissionsToSecrets Set,Get -BypassObjectIdValidation
$obj1 = ADF
$obj2 = Pipeline Application identity
Obj1(ADF) came in 'Application' section of the access policy of Key Vault
But Obj2 came in 'Unknown'section why?
Once Obj2 also came in 'Compound Identity' section .. not sure why
If you are adding an Access Policy to Key Vault for an AAD application/service principal, make sure to use the ObjectId of the service principal, which is a different ObjectId than that of the application. You can use Get-AzADServicePrincipal to retrieve the service principal and find its ObjectId.

How to import certificate from Azure?

We bought a certificate via Azure and would like to use it on same VM.
We just need .pfx file.
We tried almost everything and we are getting next error:
"You do not have permission to get the service prinicipal information
needed to assign a Key Vault to your certificate. Please login with an
account which is either the owner of the subscription or an admin of
the Active Directory to configure Key Vault settings."
But we have permissions...
#Sasha, there are not a lot of details to go on here and I hate to state the obvious given you've tried everything, but the error message is pretty clear - "You do not have permission to get the service principal information needed".
Some things to clarify and check:
Did you buy an Azure "App Service Certificate"?
Is the certificate in 'issued' status?
Are you logged in as the subscription owner or did the owner give you admin access to their subscription? The latter is not good enough, I believe.
Did you complete the three-step validation process?
If you did all of that, your certificate is now stored in an Azure Key Vault. When you create an Azure Key Vault, there is an advanced access policy option to "Enable Access to Azure Virtual Machines for deployment" (see image). Its help info reads, "Specifies whether Azure Virtual Machines are permitted to retrieve certificates stored as secrets from the key vault."
That said, since you want a .pfx file, below is a sample PowerShell script extracted from MSDN blogs to do just that. Provide appropriate values for the four "$" parameters below and save the script as copyasc.ps1.
$appServiceCertificateName = ""
$resourceGroupName = ""
$azureLoginEmailId = ""
$subscriptionId = ""
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId $subscriptionId
$ascResource = Get-AzureRmResource -ResourceName $appServiceCertificateName -ResourceGroupName $resourceGroupName -ResourceType "Microsoft.CertificateRegistration/certificateOrders" -ApiVersion "2015-08-01"
$keyVaultId = ""
$keyVaultSecretName = ""
$certificateProperties=Get-Member -InputObject $ascResource.Properties.certificates[0] -MemberType NoteProperty
$certificateName = $certificateProperties[0].Name
$keyVaultId = $ascResource.Properties.certificates[0].$certificateName.KeyVaultId
$keyVaultSecretName = $ascResource.Properties.certificates[0].$certificateName.KeyVaultSecretName
$keyVaultIdParts = $keyVaultId.Split("/")
$keyVaultName = $keyVaultIdParts[$keyVaultIdParts.Length - 1]
$keyVaultResourceGroupName = $keyVaultIdParts[$keyVaultIdParts.Length - 5]
Set-AzureRmKeyVaultAccessPolicy -ResourceGroupName $keyVaultResourceGroupName -VaultName $keyVaultName -UserPrincipalName $azureLoginEmailId -PermissionsToSecrets get
$secret = Get-AzureKeyVaultSecret -VaultName $keyVaultName -Name $keyVaultSecretName
$pfxCertObject=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList #([Convert]::FromBase64String($secret.SecretValueText),"", [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$pfxPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 50 | % {[char]$_})
$currentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
[Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
[io.file]::WriteAllBytes(".\appservicecertificate.pfx", $pfxCertObject.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $pfxPassword))
Write-Host "Created an App Service Certificate copy at: $currentDirectory\appservicecertificate.pfx"
Write-Warning "For security reasons, do not store the PFX password. Use it directly from the console as required."
Write-Host "PFX password: $pfxPassword"
Type the following commands in PowerShell console to execute the script:
Powershell –ExecutionPolicy Bypass
.\copyasc.ps1
Once the script is executed, you would see a new file in the current directory called ‘appservicecertificate.pfx’. This is a password protected PFX, the PowerShell console would display the corresponding password.

Azure Key Vault Access Policy Doesn't Work For Groups

Access policies via groups on Azure Key Vault don't seem to work.
If I create a new key vault
New-AzureRmKeyVault -VaultName $vaultName
And check the keys (which there aren't any of currently)
Get-AzureKeyVaultKey -VaultName $vaultName
That works.
If I add access to a group that the current user is a member of
$group = (Get-AzureRmADGroup -SearchString 'All Developers')[0].Id
Set-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -ResourceGroupName $resourceGroupName -ObjectId $group -PermissionsToKeys all -PermissionsToSecrets all
And remove direct access
Remove-AzureRmKeyVaultAccessPolicy -VaultName $vaultName -ResourceGroupName $resourceGroupName -UserPrincipalName $upn
The list operation now fails
Get-AzureRmKeyVault -VaultName $vaultName -ResourceGroupName $resourceGroupName
Get-AzureKeyVaultKey : Operation "list" is not allowed
How can I permission by group?
I discovered today that it works for users in permissioned group objects. Doesn't work for service principals in those groups.
In other words, if I authenticate using a client id and client secret, the associated service principal must have an access policy directly set on the key vault. If I permission a security group, a user in that group can in fact access the key vault. I guess this has something to do with how the JWT includes security groups in it with users, but not service principals...
The reason that adding an access policy to a group is that it isn't supported. If you look at the help for Set-AzureRmKeyVaultAccessPolicy there is this for ObjectId
-ObjectId <Guid>
Specifies the object ID of the user or service principal in Azure Active Directory for which to grant permissions.
Required? true
Position? named
Default value none
Accept pipeline input? true(ByPropertyName)
Accept wildcard characters? false
As you can see ObjectId only supports either Service principals or users.
This is reflected in the parameters of the source code for Set-AzureRmKeyVaultAccessPolicy and further up the chain the REST API when posting to
https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.KeyVault/vaults/{vault-name}?api-version={api-version}
The payload contains the objectId parameter which is defined as
Specifies the object ID of a user or service principal in the Azure Active Directory tenant for the vault. The ID must be specified as a GUID.
I would imagine that this functionality will be added at some point in future, but at the moment it isn't possible.
This Access Denied / 403 Forbidden error can also happen when an app has made requests to a Key Vault before it was added to the Azure Active Directory Group.
Perhaps this has something to do with caching of service principal information on the App Service instance? I was unable to find documentation of this.
Solution: restart the App Service.

Resources