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.
add
will add a new set of permission or merge them with existing if any exists for the pair objectId and tenantId.
In the case ofadd
if the principal had thelist
permission and you calladd
with theget
permission, the end result will belist, get
.replace
will create or override any existing permission with what is expressed in the template for the pair objectId and tenantId.
In the case ofreplace
if the principal hadlist, get
permissions and you callreplace
with theget
permission, the end result will beget
.delete
will delete the access policyfor the pair objectId and tenantId.
Complete example
Here is a complete and functional ARM template that use vaulName
, principalId
and 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!