How to incrementally update KeyVault access policies with ARM templates
I was recently asked how to give access to an existing KeyVault to a managed identity that already have access policies configured. It's not a secret but not all know about this little trick that will enable you to incrementally process permissions to KeyVault over time using ARM templates.
Genesis
It all started with this article on the best way to reference Managed Identity using ARM templates - there-is-a-new-way-to-reference-managed-identity-in-arm-template/
One of my readers (Sam not to name it :)) reached out with a question I got asked several times over the years. So I decided to write an article about it.
The question was:
Thanks for the article. I'm trying to assign keyvault access policies to the system-assigned identity of my webapp. However in your example a new keyvault is created. How can do that for an existing keyvault ?
My understading with this question is that he wants to update his existing KeyVault without messing with the existing acess policies. The good news is there's a way to do this, let's see how.
Incremental Access Policy update
The way to perform an incremental update of KeyVault AccessPolicies is by using a resource type named Microsoft.KeyVault/vaults/accessPolicies
You have three choice of name for the resource: add, replace or remove. As you can guess they will perform different actions on the access policy you are defining. I used add in the example below but let me summarize them rapidly.
addwill add a new set of permission or merge them with existing if any exists for the pair objectId and tenantId.
In the case ofaddif the principal had thelistpermission and you calladdwith thegetpermission, the end result will belist, get.replacewill create or override any existing permission with what is expressed in the template for the pair objectId and tenantId.
In the case ofreplaceif the principal hadlist, getpermissions and you callreplacewith thegetpermission, the end result will beget.deletewill delete the access policyfor the pair objectId and tenantId.
Complete example
Here is a complete and functional ARM template that use vaulName, principalIdand optional tenantId parameters to populate add/merge (1) access policy because of the resource name add on KeyVault vaulName.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"vaultName": {
"type": "string"
},
"principalId": {
"type": "string"
},
"tenantId": {
"type": "string",
"defaultValue": "[subscription().tenantId]"
}
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults/accessPolicies",
"name": "[concat(parameters('vaultName'), '/add')]",
"apiVersion": "2019-09-01",
"properties": {
"accessPolicies": [
{
"tenantId": "[parameters('tenantId')]",
"objectId": "[parameters('principalId')]",
"permissions": {
"keys": ["all"],
"secrets": ["all"],
"certificates": ["all"],
"storage": ["all"]
}
}
]
}
}
],
"outputs": {
}
}Hope you like this article, and Sam, that it answer your question!
Happy ARM template!