If I have a web app which has a system-assigned managed identity and the web app has been added to a Key Vault's Access Policies, I can use the following code the get secret value from the Key Vault under Kudu powershell Environment:
function GetSecret {
param (
[parameter(Mandatory=$True, Position=1)] [String] $keyVaultSecretUri
)
$apiVersion="2017-09-01"
$resourceURI = "https://vault.azure.net"
$tokenResponse = Invoke-RestMethod `
-Method Get `
-Headers @{"Secret"="$env:MSI_SECRET";"Content-Type"="application/json"} `
-Uri "${env:MSI_ENDPOINT}?resource=${resourceURI}&api-version=${apiVersion}"
$accessToken = $tokenResponse.access_token
$headers = @{'Authorization'="Bearer $accessToken"}
$keyVaultApiVersion="7.1"
$secret=Invoke-RestMethod -Method Get -Headers $headers -Uri "${keyVaultSecretUri}?api-version=${keyVaultApiVersion}"
return $secret
}
GetSecret -keyVaultSecretUri $SecreteUri
But if I give the web app a user-assigned managed identity (without system-assigned managed identity) and add that managed identity to the Key Vault's Access Policies (with enough permissions), the above code doesn't work.
Actually even the following three lines gets a runtime exception:
$apiVersion="2017-09-01"
$resourceURI = "https://vault.azure.net"
$tokenResponse = Invoke-RestMethod `
-Method Get `
-Headers @{"Secret"="$env:MSI_SECRET";"Content-Type"="application/json"} `
-Uri "${env:MSI_ENDPOINT}?resource=${resourceURI}&api-version=${apiVersion}"
The exception is (CorrelationId is hidden):
Invoke-RestMethod : {"StatusCode":400,"Message":"No MSI found for specified
ClientId/ResourceId.","CorrelationId":"0000000-0000-0000-0000-000000000000"}
At line:1 char:18
+ $tokenResponse = Invoke-RestMethod `
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:Htt
pWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShe
ll.Commands.InvokeRestMethodCommand
So how to get Key Vault Secret under Web App's (with a user-assigned managed identity) Kudu powershell environment??
(Probably the Headers for user-assigned identity web app is wrong)
PS: This answer How can I give access to key vault to a user assigned identity? doesn't resolve my question.
I actually wrote an article on this topic just a while ago: https://joonasw.net/view/get-managed-identity-access-token-in-azure-app-service-through-kudu. There I link to the docs for the REST protocol that Managed Identity uses: https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet#using-the-rest-protocol.
If you use a user-assigned identity, you must identify which identity you want to use. Since an App Service etc. can have multiple user-assigned identities. In the docs they give the following options:
You only need to specify one of these if I recall correctly.
Tested this script and got a token for the user-assigned identity:
$resource = "https://vault.azure.net"
$clientId = "00000000-0000-0000-0000-000000000000"
$endpoint = $env:IDENTITY_ENDPOINT
$header = $env:IDENTITY_HEADER
$apiVersion = "2019-08-01"
$headers = @{ 'X-Identity-Header' = $header }
$url = "$($endpoint)?api-version=$apiVersion&resource=$resource&client_id=$clientId"
$response = Invoke-RestMethod -Method Get -Uri $url -Headers $headers
$response.access_token