> ## Content Index
> Fetch the complete content index at: https://codeisahighway.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# How to audit Key Vault Access Policy using Azure Resource Graph
- URL: https://codeisahighway.com/how-to-audit-key-vault-accesspolicies-using-azure-resource-graph/
- Published: 2019-07-25T20:26:41.000Z
- Updated: 2026-08-10T07:12:57.000Z
- Author: Stephane Lapointe
- Tags: Microsoft Azure, Azure Resource Graph, Azure Key Vault, Compliance, HowTo, Audit, #Import 2023-07-11 16:44, #Import 2026-09-04 10:31, #Import 2026-09-04 13:56

If you didn't know it yet, I am a big fan of Azure Resource Graph. It gives me the ability to quickly answer business inquiries / people showing at my desk with questions regarding Azure resources. I got one last week: "What is all the Key Vault where "UserX" has access". Seems complicated? Not at all, follow me.

If you need a quick intro or refresh about what is Azure Resource Graph, [jump here](https://codeisahighway.com/how-azure-resource-graph-is-gonna-change-the-way-you-search-and-script).

### The requirement

Like stated above, the need was, please tell me all the Azure Key Vault instances where "UserX" (who is an admin) forgot to clean his access/remove itself after his maintenance ticket.

### How I solved it

What I first did is query Azure Resource Graph to see the definition/properties I get for an Azure Key Vault instance, just to see if its definition contains the information I needed (in this case Access Policy)

```
where type =~ "Microsoft.KeyVault/vaults"
| limit 1
```

it returned me the following properties:

```
{
    "provisioningState": "RegisteringDns",
    "tenantId": "4f9ff0ff-bbb7-4cd0-ac4d-f8aea3f93bf6",
    "sku": {
        "name": "Standard",
        "family": "A"
    },
    "enabledForTemplateDeployment": false,
    "enabledForDiskEncryption": false,
    "enabledForDeployment": false,
    "accessPolicies": [
        {
            "permissions": {
                "secrets": [
                    "Get",
                    "List",
                    "Set",
                    "Delete",
                    "Recover",
                    "Backup",
                    "Restore"
                ],
                "certificates": [
                    "Get",
                    "List",
                    "Update",
                    "Create",
                    "Import",
                    "Delete",
                    "Recover",
                    "Backup",
                    "Restore",
                    "ManageContacts",
                    "ManageIssuers",
                    "GetIssuers",
                    "ListIssuers",
                    "SetIssuers",
                    "DeleteIssuers"
                ],
                "keys": [
                    "Get",
                    "List",
                    "Update",
                    "Create",
                    "Import",
                    "Delete",
                    "Recover",
                    "Backup",
                    "Restore"
                ]
            },
            "tenantId": "4f9ff0ff-bbb7-4cd0-ac4d-f8aea3f93bf6",
            "objectId": "5eaecd00-b76e-47ab-8645-16d9a75f5757"
        },
        {
            "permissions": {
                "secrets": [
                    "Get",
                    "List",
                    "Set",
                    "Delete",
                    "Recover",
                    "Backup",
                    "Restore"
                ],
                "certificates": [],
                "keys": []
            },
            "tenantId": "4f9ff0ff-bbb7-4cd0-ac4d-f8aea3f93bf6",
            "objectId": "5a99e6db-4ec7-43ac-9585-25eee5b479df"
        }
    ],
    "vaultUri": "https://key-vault-resource-graph.vault.azure.net/"
}
```

I found the information I need under the property `accessPolicies`. Now I needed to find the `objectId` of "UserX", this is easy, using PowerShell or Azure CLI, I can look it up.

```
# Azure CLI
az ad user show --upn "userx@mycompany.com" --query objectId

#PowerShell
Get-AzADUser -UserPrincipalName 'userx@mycompany.com' | Select-Object -ExpandProperty Id
```

Once I have this information, I can now build up the Resource Graph query to ask about all Key Vault where this `objectId` is present in the `accessPolicies`.

```
where type =~ "Microsoft.KeyVault/vaults"
| mvexpand policy = properties.accessPolicies
| where policy.objectId == '5a99e6db-4ec7-43ac-9585-25eee5b479df'
| project name, resourceGroup
```

### Let's Understand What This Query Does

The secret sauce here is `mvexpand`. It will expand a multi-value array or property bag into separate results, allowing you to query each item in the `accessPolicies` array.

1. It will first filter to only return types `Microsoft.KeyVault/vaults` (Key Vault).
2. It will extend the result set by creating a separate row for each accessPolicies in that Key Vault.
3. It will filter results to the `objectId` we looked up earlier.

### Use it as often as possible

I invite you to play more and more with Azure Resource Graph, it is a very valuable tool in your tool belt. In all transparency, this is the original query I use to lookup the information I needed last week: 

```
where type =~ "Microsoft.Keyvault/vaults"
| extend p=todynamic(properties)
| extend policies=todynamic(tostring(p.accessPolicies)) 
| mvexpand policy = policies 
| where tostring(policy.objectId) == '5a99e6db-4ec7-43ac-9585-25eee5b479df'
| project name, resourceGroup
```

I originally took pieces here and there from Log Analytics query I had for policies and compliance . Taking a step back after, I was able to trim it to be more effective. We learn every day!

### Resources

- [Azure Data Explorer Query Language reference](https://docs.microsoft.com/en-us/azure/kusto/query/?ref=codeisahighway.com)
- [mvexpand documentation](https://docs.microsoft.com/en-us/azure/kusto/query/mvexpandoperator?ref=codeisahighway.com)