Key Vault Contributorなのにシークレットを取得できない原因とRBAC確認手順

Key Vault Contributorを付与したのに、アプリからAzure Key Vaultのシークレットを取得できず、403エラーになることがあります。

この場合、最初に確認すべきなのは権限の種類と付与先のIDです。Key Vault Contributorは、Vaultの作成や設定変更などを行う管理プレーンのロールであり、シークレット値を読み取るデータプレーン権限を含みません。

対象Vaultのアクセス許可モデルが「Azure RBAC」か「アクセスポリシー」かを確認し、実際にKey VaultへアクセスしているマネージドIDやサービスプリンシパルへ、必要なデータプレーン権限を付与します。Azure RBAC方式でシークレット値の読み取りだけが必要なら、代表的なロールは「Key Vault Secrets User」です。「Key Vault Reader」ではシークレットの名前や属性は確認できますが、値は取得できません。([Microsoft Learn][1])

目次

Key Vaultを管理できるのにシークレットを読めない理由

Azure Key Vaultへのアクセスは、大きく「管理プレーン」と「データプレーン」に分かれます。

区分主な操作権限を制御する仕組み
管理プレーンVaultの作成、削除、設定変更、タグ変更などAzure RBAC
データプレーンシークレット値の取得、登録、削除、キー操作などAzure RBACまたはアクセスポリシー

Key Vault Contributorが対象とするのは、主に管理プレーンです。

そのため、次のような状態は矛盾ではありません。

  • AzureポータルでKey Vaultを開ける
  • Vaultの設定やプロパティを確認できる
  • Key Vault Contributorが割り当てられている
  • それでもアプリからシークレット値を取得すると403になる

Vaultを管理できることと、Vault内に保存された機密情報を読めることは、別の権限として扱われます。Microsoftの組み込みロール定義でも、Key Vault ContributorにはデータプレーンのDataActionsが含まれていません。([Microsoft Learn][1])

Key Vault関連ロールの違い

シークレット取得時に混同しやすいロールを整理すると、次のようになります。

ロールシークレット値の読み取りシークレットの更新主な用途
Key Vault Contributor不可不可Vaultリソース自体の管理
Key Vault Reader不可不可キー、証明書、シークレットのメタデータ確認
Key Vault Secrets User不可アプリによるシークレット値の読み取り
Key Vault Secrets Officerシークレットの作成、更新、削除など
Key Vault AdministratorVault内のキー、証明書、シークレット全般の管理

アプリが既存のシークレットを読むだけなら、Key Vault Secrets OfficerやKey Vault Administratorを付与する必要は通常ありません。書き込みや削除まで許可してしまうため、Key Vault Secrets Userから検討するのが基本です。

また、名前に「Reader」が含まれていても、Key Vault Readerは機密値を読み取るロールではありません。シークレットの値を取得できるのは、getSecretに相当するデータアクションを持つロールです。([Microsoft Learn][1])

403エラーを切り分ける確認手順

対象Vaultのアクセス許可モデルを確認する

Azure Key Vaultのデータプレーンには、次の2種類のアクセス許可モデルがあります。

  • Azureロールベースのアクセス制御
  • 従来のVaultアクセスポリシー

どちらを使用しているかによって、権限の付与方法が変わります。

Azure RBAC方式のVaultにアクセスポリシーを追加しても、そのポリシーはシークレット取得の判定に使われません。反対に、アクセスポリシー方式のVaultへKey Vault Secrets Userを付与しても、データプレーンのアクセス許可としては使われません。([Microsoft Learn][2])

Azure CLIでは、次のように確認できます。

az keyvault show \
  --name <vault-name> \
  --resource-group <resource-group> \
  --query properties.enableRbacAuthorization \
  --output tsv

結果の見方は次のとおりです。

結果アクセス許可モデル
trueAzure RBAC
falseVaultアクセスポリシー

値が取得できない場合は、Azureポータルの対象Vaultでもアクセス許可モデルを確認してください。画面名称はポータル更新で変わる可能性がありますが、Vaultのアクセス構成または権限モデルに関する設定から確認できます。

実際にアクセスしているアプリのIDを確認する

権限の付与先は、「アプリの名前」ではなく、Key Vaultへアクセストークンを提示しているセキュリティプリンシパルです。

代表的なアクセス主体には、次のものがあります。

実行環境実際に使われる可能性があるID
ローカル開発環境Azure CLIやVisual Studioにサインインしているユーザー
App Service、Functions、VMなどシステム割り当てマネージドID
複数リソースで共通IDを使う構成ユーザー割り当てマネージドID
クライアントシークレットや証明書で認証サービスプリンシパル

よくあるのは、開発者ユーザーへ権限を付けたものの、本番環境ではマネージドIDが使われているケースです。

また、ユーザー割り当てマネージドIDをAzureリソースへ接続しただけでは、アプリが必ずそのIDを使用するとは限りません。複数のIDが存在する構成では、アプリ側で使用するクライアントIDなどを明示する必要があります。

ローカル開発時のDefaultAzureCredentialは、Azure CLIやVisual Studioなどの開発者資格情報を利用することがあります。一方、Azure上ではマネージドIDを使用する構成が一般的です。ローカルで成功したという事実だけでは、本番アプリのマネージドIDにも権限があるとは判断できません。([Microsoft Learn][3])

クライアントIDとプリンシパルIDを混同しない

ユーザー割り当てマネージドIDには、クライアントIDとプリンシパルIDがあります。

  • クライアントID:アプリ側で使用するマネージドIDを指定するときに使う
  • プリンシパルID:Azure RBACの割り当て対象として使う
  • オブジェクトID:マネージドIDではプリンシパルIDと同じ意味で扱われる

Azure CLIの--assignee-object-idには、クライアントIDではなくプリンシパルIDを指定します。([Microsoft Learn][4])

ユーザー割り当てマネージドIDのプリンシパルIDは、次の例で確認できます。

az identity show \
  --resource-group <identity-resource-group> \
  --name <managed-identity-name> \
  --query principalId \
  --output tsv

システム割り当てマネージドIDの場合は、アプリを実行しているAzureリソースの「ID」設定などからプリンシパルIDを確認します。

Azure RBAC方式でロール割り当てを確認する

VaultのリソースIDを取得する

VAULT_ID=$(az keyvault show \
  --name <vault-name> \
  --resource-group <resource-group> \
  --query id \
  --output tsv)

実際のプリンシパルに付いたロールを確認する

az role assignment list \
  --assignee-object-id <principal-id> \
  --scope "$VAULT_ID" \
  --include-inherited \
  --output table

--include-inheritedを付けると、Vault自体だけでなく、リソースグループやサブスクリプションなどの上位スコープから継承された割り当ても確認できます。([Microsoft Learn][4])

確認するときは、ロール名だけでなく、次の3点を合わせて見ます。

  • 割り当て先のプリンシパルIDがアプリの実体と一致しているか
  • ロールにシークレット値の読み取り権限があるか
  • 割り当てスコープに対象Vaultが含まれているか

別の開発環境用Vaultや、名前の似たマネージドIDへ付与していることもあります。プリンシパルIDとVaultのリソースIDを文字列で照合するのが確実です。

読み取り専用ならKey Vault Secrets Userを付与する

アプリが既存シークレットの値を読むだけなら、Key Vault Secrets Userを候補にします。

Key Vault Secrets Userの組み込みロールIDは、次の値です。

4633458b-17de-408a-b874-0445c86b69e6

マネージドIDまたはサービスプリンシパルへ付与する例は次のとおりです。

az role assignment create \
  --assignee-object-id <principal-id> \
  --assignee-principal-type ServicePrincipal \
  --role 4633458b-17de-408a-b874-0445c86b69e6 \
  --scope "$VAULT_ID"

ロール名でも指定できます。

az role assignment create \
  --assignee-object-id <principal-id> \
  --assignee-principal-type ServicePrincipal \
  --role "Key Vault Secrets User" \
  --scope "$VAULT_ID"

継続的に使用する自動化スクリプトでは、ロール名の変更による影響を避けるため、ロールIDを使う方法が適しています。Microsoftのドキュメントでも、スクリプトでは一意のロールIDを使う方法が推奨されています。([Microsoft Learn][1])

ロールを付与するスコープ

ロールは、サブスクリプション、リソースグループ、個別のVault、個別のシークレットなどに割り当てられます。

アプリ単位、環境単位でVaultを分けている場合は、対象Vaultのスコープへ割り当てる方法が分かりやすく、権限も限定できます。

スコープ特徴
サブスクリプション対象が広く、通常のアプリには過剰になりやすい
リソースグループ同じグループ内の複数Vaultへ権限が及ぶ
Key Vault対象Vault内のシークレットを利用する一般的な構成
個別シークレット特定のシークレットだけを共有する限定的な構成

Microsoftは、アプリと環境ごとにVaultを分け、Vaultスコープでロールを割り当てる構成を推奨しています。個別シークレットへの割り当ては、特別な共有要件がある場合などに限定して検討します。([Microsoft Learn][1])

アクセスポリシー方式の場合の対応

対象Vaultがアクセスポリシー方式なら、Azure RBACのデータプレーンロールではなく、アクセスポリシーへアプリのIDを追加します。

既知のシークレット名を指定して値を取得するだけなら、基本的に必要なのはget権限です。

az keyvault set-policy \
  --name <vault-name> \
  --object-id <principal-id> \
  --secret-permissions get

アプリがシークレットを列挙する必要がある場合は、要件を確認したうえでlistも追加します。

az keyvault set-policy \
  --name <vault-name> \
  --object-id <principal-id> \
  --secret-permissions get list

ここで指定するobject-idも、権限を与えたいマネージドIDやサービスプリンシパルのオブジェクトIDです。([Microsoft Learn][5])

アクセスポリシー方式では、Key Vault ContributorなどMicrosoft.KeyVault/vaults/writeを持つユーザーがアクセスポリシーを変更し、自分自身へデータプレーン権限を付与できる構成になります。この分離の弱さから、MicrosoftはAzure RBAC方式を推奨しています。([Microsoft Learn][2])

ロールを割り当てる担当者にも権限が必要

Key Vault Contributorを持っていても、Azure RBAC方式でロール割り当てを作成できるとは限りません。

ロール割り当てには、Microsoft.Authorization/roleAssignments/writeなどの権限が必要です。代表的には、次のロールを持つ担当者が実施します。

  • Owner
  • User Access Administrator
  • Key Vault Data Access Administrator

Key Vault Data Access Administratorは、Key Vault Administrator、Key Vault Secrets User、Key Vault Readerなど、対象となるKey Vaultデータプレーンロールの割り当てを管理するためのロールです。

Azureポータルで「ロールの割り当ての追加」が無効になっている場合や、Azure CLIでAuthorizationFailedになる場合は、アプリ側ではなく、割り当てを実行している管理者の権限を確認してください。([Microsoft Learn][1])

権限反映後は同じIDで取得を確認する

ロールを付与した後は、反映まで数分かかる場合があります。Azureポータルを使用している場合は、画面の再読み込みも行います。([Microsoft Learn][1])

確認では、管理者ユーザーではなく、実際のアプリと同じIDを使用することが重要です。

Azure CLIを同じプリンシパルで認証できている場合は、次のように戻り値をシークレットIDだけに限定できます。

az keyvault secret show \
  --vault-name <vault-name> \
  --name <secret-name> \
  --query id \
  --output tsv

この確認は、Azure CLIがアプリと同じマネージドIDまたはサービスプリンシパルで認証されている場合にのみ有効です。自分の管理者アカウントで実行して成功しても、アプリの権限が直った証明にはなりません。

アプリ側で確認する場合も、ログには次の情報だけを記録します。

  • 取得成功または失敗
  • HTTPステータス
  • エラーコード
  • リクエストID
  • 実行日時
  • 使用したプリンシパルID

シークレット値そのものはログへ出力しないでください。

よくある誤った対応

Key Vault Contributorを付け直す

Key Vault Contributorにはシークレット値の読み取り権限がありません。付与し直したり、上位スコープへ広げたりしても、データプレーン権限の不足は解決しません。

Key Vault Readerを追加する

Key Vault Readerは、シークレットの名前や属性などのメタデータを読むためのロールです。シークレット値の取得にはKey Vault Secrets Userなどが必要です。

開発者ユーザーへ権限を付ける

ローカルでは開発者ユーザー、本番ではマネージドIDという構成がよくあります。本番アプリが使用するプリンシパルIDへ付与しなければ、アプリの403は解消しません。

アプリ名だけで付与先を判断する

同じような名前のマネージドID、サービスプリンシパル、アプリ登録が存在することがあります。表示名ではなく、プリンシパルIDで確認します。

最初からSecrets OfficerやAdministratorを付ける

読み取りだけのアプリへ、作成、更新、削除まで可能なロールを付けるのは過剰です。必要な操作からロールを逆算します。

アプリの操作検討するロール
既存シークレットの値を読むKey Vault Secrets User
シークレットを作成、更新、削除するKey Vault Secrets Officer
キー、証明書、シークレット全般を管理するKey Vault Administrator
メタデータだけを確認するKey Vault Reader

403だけを理由にRBACへ切り替えない

アクセスポリシー方式のVaultで403が発生したからといって、原因確認をせずAzure RBAC方式へ切り替えるのは危険です。

アクセス許可モデルをAzure RBACへ変更すると、既存のアクセスポリシーによる権限は無効になります。同等のAzure RBACロールが用意されていなければ、アプリ、バッチ処理、運用ツールなどが一斉にKey Vaultへアクセスできなくなる可能性があります。([Microsoft Learn][1])

切り替えを行う場合は、少なくとも次の対象を洗い出します。

  • アプリケーション
  • マネージドID
  • サービスプリンシパル
  • 運用担当ユーザー
  • バックアップや監視処理
  • CI/CDパイプライン
  • 証明書更新処理
  • シークレットを参照するAzureサービス

403の解消だけが目的なら、まず現在のアクセス許可モデルを維持したまま、ID、権限、スコープの不一致を修正してください。

対象外となるサービス

ここまでの説明は、Azure Key Vaultのvaultsリソースを対象としています。

Managed HSMはアクセス制御の仕組みが異なるため、この記事のKey Vault Contributor、Key Vault Secrets User、Vaultアクセスポリシーに関する手順をそのまま適用することはできません。([Microsoft Learn][1])

Key Vaultの403はモデル、ID、ロール、スコープの順で確認する

Key Vault Contributorなのにアプリからシークレット取得が拒否される場合、確認する順番は次のとおりです。

  1. 対象VaultがAzure RBAC方式かアクセスポリシー方式か確認する
  2. アプリが実際に使用しているプリンシパルIDを特定する
  3. そのIDにデータプレーン権限が付いているか確認する
  4. Azure RBAC方式なら、読み取り用途にKey Vault Secrets Userを検討する
  5. Vault、リソースグループ、サブスクリプションなど、割り当てスコープを確認する
  6. 反映後はアプリと同じIDで取得を再確認する
  7. シークレット値はテスト結果やログへ出力しない

「Vaultを管理できるからシークレットも読める」と考えず、管理プレーンとデータプレーンを分けて確認することが、最短の切り分け方法です。
[1]: https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-guide “Grant permission to applications to access an Azure key vault using Azure RBAC | Microsoft Learn”
[2]: https://learn.microsoft.com/en-us/azure/key-vault/general/rbac-access-policy “Azure role-based access control (Azure RBAC) vs. access policies | Microsoft Learn”
[3]: https://learn.microsoft.com/en-us/dotnet/azure/sdk/authentication/user-assigned-managed-identity “Authenticate Azure-hosted .NET apps to Azure resources using a user-assigned managed identity – .NET | Microsoft Learn”
[4]: https://learn.microsoft.com/en-us/cli/azure/role/assignment?view=azure-cli-latest “az role assignment | Microsoft Learn”
[5]: https://learn.microsoft.com/en-us/azure/key-vault/general/assign-access-policy “Assign an Azure Key Vault access policy (CLI) | Microsoft Learn”

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次