1
votes

I have msi added to VMSS, by checking ComputerResourceGroupInfo.json in ElasticAPV2.xts, I have:

"ManagedServiceIdentityConfig": {
          "Type": "SystemAssigned, UserAssigned",
          "**UserAssignedIdentities**": [
            "/subscriptions/1234567890qwer/resourceGroups/my-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-msi"
          ],
          "ServicePrincipalForSystemAssignedIdentity": "...",
          "ScaleSetIdentity": {
            "principalId": "...",
            "tenantId": "...",
            "type": "SystemAssigned, UserAssigned",
            "**userAssignedIdentities**": {
              "/subscriptions/1234567890qwer/resourceGroups/my-rg/providers/Microsoft.ManagedIdentity/userAssignedIdentities/my-msi": {
                "principalId": "...",
                "clientId": "..."
              }

my-msi is also added to Azure Key Vault access policy with List and Get.

In the VM, Itried to get secret using

PS D:\ManagementServiceCommonSetup> $accessToken = (Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net' -Method GET -Headers @{Metadata="true"} -UseBasicParsing | ConvertFrom-Json).access_token
PS D:\ManagementServiceCommonSetup> echo $accessToken
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IkN0ZlFDOExlLThOc0M3b0MyelFrWnBjcmZP...MCQi-bPCJQ
PS D:\ManagementServiceCommonSetup> (Invoke-WebRequest -Uri https://my-kv.vault.azure.net/certificates/my-cert/587898f2?api-version=2016-10-01 -Method GET -Headers @{Authorization="Bearer $accessToken"}).content
Invoke-WebRequest : {"error":{"code":"Forbidden","message":"Access denied","innererror":{"code":"AccessDenied"}}}
At line:1 char:2
+ (Invoke-WebRequest -Uri https://my-kv.vault.azure.net/secrets/my-cert/ ...
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

My questions:

  1. Is this right way to retrieve certificate using access token through user-assigned identity?
  2. Why the access got denied? My understanding is Access control (IAM) is not need here since I have add msi to access policies.

Update:

For user assigned identity, need to specify object id or client id.

Invoke-WebRequest -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net&object_id=$($ObjectId)" -Method GET -Headers @{Metadata="true"}
3

3 Answers

2
votes

1.Is this right way to retrieve certificate using access token through user-assigned identity?

No, the Uri you used is to get secret, if you want to get a certificate, it should be

Invoke-WebRequest -Uri https://my-kv.vault.azure.net/certificates/my-cert/587898f2?api-version=2016-10-01 -Method GET -Headers @{Authorization="Bearer $accessToken"}

Reference : Get Certificate - Get Certificate

2.Why the access got denied? My understanding is Access control (IAM) is not need here since I have add msi to access policies.

Your understanding is right. Check it in the Access policies again, make sure you have given the Certificate permissions (you can also try Select all, it is convenient).

enter image description here

Update:

I test it in a windows vm, in the vmss, the logic should be the same, the doc of VM and VMSS to access the keyvault is together.

And if I test with a system-assigned identity, it works fine. If I test it with a user-assigned managed identity, I also get the 403 error.

The user-assigned managed identity is a Preview feature, I am not sure if it support to access keyvault, the doc is just for system-assigned identity. So I recommend you to use system-assigned identity to access keyvault, you could have a try.

$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
$content = $response.Content | ConvertFrom-Json 
$KeyVaultToken = $content.access_token 
(Invoke-WebRequest -Uri https://<keyvault-name>.vault.azure.net/certificates/<{certificate-name}>/<certificate-version>?api-version=2016-10-01 -Method GET -Headers @{Authorization="Bearer $KeyVaultToken"} -UseBasicParsing).content 

system-assigned identity:

enter image description here

user-assigned managed identity:

enter image description here

0
votes

For user assigned identity, need to specify object id or client id.

 Invoke-WebRequest -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://vault.azure.net&object_id=$($ObjectId)" -Method GET -Headers @{Metadata="true"}
0
votes

@Daolin, I tested the same scenario of requesting for an Access Token from AAD using the UserManagedIdentity.

The following cmd worked for me:

$response1 = Invoke-WebRequest -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/&object_id=xxxxxx-xxxx-xxxx-xxxxx-xxxxx" -UseBasicParsing -Method GET -Headers @{Metadata="true"}   

Now, object is the PrincipalID/ObjectID. The ClientID didnt work for me. FOr my case I am using an Azure VM with both SystemManagedIdentity and UserManagedIdentity both enabled. Hence, when I request for an Access Token using the clientID as the query parameter it issues me an access token with the objectID of the System Managed Identity in it.