Milhouse Manastorm
Milhouse Manastorm

Reputation: 37

How to get Key Vault Secret under Web App's (with a user-assigned managed identity) Kudu powershell environment?

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.

Upvotes: 0

Views: 637

Answers (1)

juunas
juunas

Reputation: 58773

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:

Three query parameters that can be specified

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

Upvotes: 1

Related Questions