Azure と AWS でそれぞれアプリケーションが稼働していて、外部の API に対して利用するクライアント Id、シークレットを同じものを使いたいという状況はそれなりにあると思います。(要出典
ですが、KeyVault は、Entra 認証が必要なため、Azure 内のシステムからでないと少しアクセス方法がややこしいです。
ということで、連携方法をまとめます。
今回の仕組み
今回構築する仕組みは、Workload Identity Federation の仕組みを利用して、Cognito と User assigned managed Identity を federate して実現します。
実際にやってみる
ステップ01
User assigned managed identity を作成します
とりあえずポータルからポチポチでも何でも良いので、適当に作成します。
ステップ02
Key Vault を作成します。
こちらも、ポータルからポチポチでも何でも良いので、適当に作成します。
作成した Managed Identity に Key Vault の権限を付与する
とりあえず下記3つを IAM で付与します。
- Key Vault Certificate User
- Key Vault Secrets User
- Key Vault Crypto Service Encryption User
Cognito を作ったりするように AWS に IAM ユーザを作る
Root ユーザは怖いので、IAM ユーザを作りましょう
次の2つの権限を割り当てた IAM ユーザがあれば OK です
- AmazonCognitoPowerUser
- AWSCloudShellFullAccess
※ iam:create-role
が無いと、Cognito 作成時にエラーが出ますが、今回はあくまで Azure と Federate するだけで、
AWS 内で何かする権限は必要ないので、このままで OK です。
ステップ03
Cognito を作る
ID プールを作る
分かりづらいですが、プルダウンから、 AWS のサービスへのアクセス権を付与する選択して、ID プールを作成を選択します。
ID プールの信頼設定
下記の設定で次へを選択します。
- ユーザアクセス : 認証されたアクセス
- 認証された ID ソース : カスタムデベロッパープロバイダー
許可を設定
下記の設定で次へを選択します。
※ IAM ロールを作成する権限が無いはずなので、あとでエラーになります。
- IAM ロール : 新しい IAM ロールを作成
- IAM ロール名に適当な名前を入れる
ID プロバイダーを接続する
下記の設定で次へを選択します。
プロパティを設定する
ID プール名に適当な名前を入れて次へを選択します。
確認と作成
確認画面で、問題が無さそうなら、ID プールを作成を選択します。
ステップ04
Cognito の設定をする
Identity プールに Identity を作成する
ここからコマンドを流す必要があります。
AWS CLI が必要なので、CloudSehll を使いましょう
CloudShell で下記のコマンドを流します。
aws cognito-identity get-open-id-token-for-developer-identity \
--identity-pool-id {ID プールの id} \
--logins {デベロッパープロバイダー名}={適当なテキスト(managed id の client id とか)}
コマンドを流すと下記のような json が取れるので、Token の値を jwt デコーダでデコードします。
{
"Token": "{jwt トークン}",
"IdentityId": "{登録した Identity の Id}"
}
ステップ05
Managed Identity と Cognito を federate する
Azure CLI を使うので、Azure CLI が使える環境をご用意ください
下記のコマンドを流します。(PowerShell 前提になっているので、他のシェルを使う場合は、改行の調整をしてください)
az identity federated-credential create `
--name {Managed Identity の Federated credentials として登録する名前} `
--identity-name {managed identity の名前} `
--resource-group {resource group の名前} `
--issuer {jwt から取得した iss} `
--subject {jwt から取得した sub} `
--audience {jwt から取得した aud}
ステップ06
Cognito のトークンを使って Azure にログインする
まず、Cognito からトークンを取得します。
ステップ04 で流したコマンドをもう一度流して、トークンを取得します。
下記のコマンドで Azure CLI からログインします。
az login --federated-token {cognito から取得したトークン(jwt)} `
--tenant {Entra のテナント Id} `
--service-principal -u {managed identity の client id}
ステップ07
KeyVault へアクセスできるかをチェックする
とりあえず Secrets を取得してみましょう
az keyvault secret list --vault-name {key vault の名前}
エラーが出なければ、成功です。
ステップ07
REST API を使って、Key Vault にアクセスする
Azure へのアクセストークンを取得する
下記の設定で API を呼びます。(Postman 等を使いましょう)
リクエスト Body
Key |
Value |
client_id |
{Managed Identity の Client Id} |
grant_type |
client_credentials |
scope |
{必要な scope 設定。Key Vault の場合は、https://vault.azure.net/.default} |
client_assertion |
{Cognito のトークン} |
client_assertion_type |
urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
下記のレスポンスが返ってきます。
{
"token_type": "Bearer",
"expires_in": {有効期限(秒)},
"access_token": "{アクセストークン}"
}
Key Vault を呼び出す
認証
Bearer {取得したアクセストークン}
Secrets を取得する
- Endpoint : {KeyVault エンドポイント}/secrets?maxresults=1&api-version=7.4
- メソッド : GET
まとめ
これで、AWS の環境から KeyVault にアクセスできるようになりました。
Managed Identity で接続できるサービスは、権限を調整すればこれで接続できるはずです。
世の中にある大抵のシステムは、パブリッククラウドを跨いで何かするということは無いと思いますが、いざというときに使えると便利です。
SDK を使った方法については気が向いたらまとめようと思います。