Azureリソースのマネージド ID(旧MSI)の権限をCURLでREST APIを実行して検証する

最近、AKSも対応したマネージド ID(旧MSI)です。これで認証情報をローカルに持たなくてもAPIが叩けるようになりました。

docs.microsoft.com

権限の検証はAzure CLIやSDKでも検証できますが、ここでは手っ取り早くcurlで検証する方法を記載します。

仮想マシンやコンテナにログオン

仮想マシンならSSHでログインすれば良いですが、最近マネージドIDに対応したAKSの場合も以下のように接続用の一時podを立ち上げれば同じことが可能です。

kubectl run --generator=run-pod/v1 -it --rm aks-ssh --image=debian

curlとjqをインストール

必要なのはAPI叩く用の curl と、結果を表示する用の jq です。

jq はあった方が便利ですが必須ではないです。その場合はコピペで進めてください。

apt update && apt install -y curl jq

AccessTokenを取得

まずは仮想マシンなどに紐付けられたAccess Tokenを取得します。

$ token=$(curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' -H Metadata:true -s | jq -r '.access_token')

Tokenの中身は以下のサイトで確認できます。

jwt.ms

REST APIのURLを作成

AzureのREST APIは以下のツールで探すことができます。ここではServiceBusのAPIを検索しています。

REST API ブラウザー | Microsoft Docs

今回はQueueの情報を取得するAPIを実行してみます。

Queues - Get (Azure Service Bus) | Microsoft Docs

ページにある情報からRest APIのURLを作成します。変数はページ上記のページに合わせて subscriptionIdresourceGroupName 用に小文字始まりのCamelCaseで書いておくと便利です。

subscriptionId=12345678-1234-1234-abcd-123456abcdef
resourceGroupName=my-rg
namespaceName=my-sbn # ServiceBus Namespaceの名前
queueName=my-sbq   # ServiceBus Queueの名前
apiVersion=2017-04-01
url=https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.ServiceBus/namespaces/${namespaceName}/queues/${queueName}?api-version=${apiVersion}

REST API実行

REST APIのURLを入れた ${url} と、Access Tokenを入れた ${token} を使ってCURLを実行します。

curl -s ${url} -H "Authorization:Bearer ${token}" | jq

権限が無い場合の実行例です。

$ curl -s ${url} -H "Authorization:Bearer ${token}" | jq
{
  "error": {
    "code": "AuthorizationFailed",
    "message": "The client 'xxxx' with object id 'xxxx' does not have authorization to perform action 'Microsoft.ServiceBus/namespaces/queues/read' over scope '/subscriptions/12345678-1234-1234-abcd-123456abcdef/resourceGroups/my-rg/providers/Microsoft.ServiceBus/namespaces/my-sbn/queues/my-sbq' or the scope is invalid. If access was recently granted, please refresh your credentials."
  }
}

権限を持っている場合の実行例です。

$ curl -s ${url} -H "Authorization:Bearer ${token}" | jq
{
  "id": "/subscriptions/12345678-1234-1234-abcd-123456abcdef/resourceGroups/my-rg/providers/Microsoft.ServiceBus/namespaces/my-sbn/queues/my-sbq",
  "name": "my-sbq",
  "type": "Microsoft.ServiceBus/Namespaces/Queues",
  "location": "Japan East",
  "properties": {
    "lockDuration": "PT1M",
    "maxSizeInMegabytes": 81920,
    "requiresDuplicateDetection": false,
    "requiresSession": false,
    "defaultMessageTimeToLive": "P14D",
    "deadLetteringOnMessageExpiration": false,
    "enableBatchedOperations": true,
    "duplicateDetectionHistoryTimeWindow": "PT10M",
    "maxDeliveryCount": 10,
    "sizeInBytes": 1716,
    "messageCount": 8,
    "status": "Active",
    "autoDeleteOnIdle": "P10675199DT2H48M5.4775807S",
    "enablePartitioning": true,
    "enableExpress": false,
    "countDetails": {
      "activeMessageCount": 8,
      "deadLetterMessageCount": 0,
      "scheduledMessageCount": 0,
      "transferMessageCount": 0,
      "transferDeadLetterMessageCount": 0
    },
    "createdAt": "2020-04-13T06:57:32.12Z",
    "updatedAt": "2020-04-13T09:42:19.913Z",
    "accessedAt": "2020-04-13T09:44:12.7926436Z"
  }
}