How to get the System Assigned Managed Identity Object Id from within the VM?

2 minute read

While working with Terraform and Azure DevOps self-hosted agent, I faced a challenge getting the Object(Principal) Id of a System Assigned Managed Identity to the VM running the agent. I needed that Object Id to assign access to a Key Vault. There is a way to do so via Azure CLI:

az resource list -n $(curl -s -H Metadata:true --noproxy '*' '' | jq -r -g $(curl -s -H Metadata:true --noproxy '*' '' | jq -r .compute.resourceGroupName) --query '{principal_id:[0].identity.principalId,tenant_id:[0].identity.tenantId}' --out json

but that approach requires the installation of Azure CLI and configuring Reader access on the VM itself.

A more elegant approach is to extract the Object Id from the access token received by calling the Azure Instance Metadata Service (IMDS) endpoint:

curl "" --header "Metadata: true" | jq -r .
access_token | jq -R 'split(".") | .[1] | @base64d | fromjson | .oid' -r

In Terraform, you can use the external provider to execute the script:

data "external" "account_info" {
  program = ["bash", "-c", "curl -s '' --header 'Metadata: true' | jq -r .access_token | jq -R 'split(\".\") | .[1] | @base64d | fromjson | {oid: .oid, appid: .appid,tid: .tid}'"]

and then access the Object Id (and the Tenant Id) with:


For example:

resource "azurerm_key_vault_access_policy" "current-user" {
  key_vault_id =

  tenant_id = tomap(data.external.account_info.result).tid
  object_id = tomap(data.external.account_info.result).oid

  key_permissions = [