2 セットの認証資格情報があるリソースを対象にシークレットのローテーションを自動化する

Azure サービスに対する認証を行う最善の方法はマネージド ID を使用することですが、この方法を選択できないシナリオもあります。 このような場合は、アクセス キーまたはパスワードが使用されます。 アクセス キーとパスワードは頻繁にローテーションする必要があります。

このチュートリアルでは、2 セットの認証資格情報を使用するデータベースとサービスを対象に、シークレットの定期的なローテーションを自動化する方法について説明します。 具体的には、Azure Key Vault にシークレットとして格納されている Azure ストレージ アカウント キーをローテーションする方法について説明します。 Azure Event Grid の通知によってトリガーされる関数を使用します。

Note

ストレージ アカウント サービスの場合は、Microsoft Entra ID を使用して要求を承認することをお勧めします。 詳しくは、Microsoft Entra ID を使用した BLOB へのアクセスの認可に関する記事をご覧ください。 アクセス キーと共にストレージ アカウントの接続文字列を必要とするサービスがあります。 そのようなシナリオで、このソリューションは推奨されます。

このチュートリアルで説明するローテーション ソリューションを次に示します。

ローテーション ソリューションを示す図。

このソリューションでは、ストレージ アカウントの個々のアクセス キーが、同じシークレットの別バージョンとして Azure Key Vault に格納され、プライマリとセカンダリのキーが後続のバージョンで交互に入れ替わります。 最新バージョンのシークレットにアクセス キーが格納されるときは、代替キーが再生成されて、新たな最新バージョンのシークレットとして Key Vault に追加されます。 このソリューションによって、再生成された最新のキーに更新するための完全なローテーション サイクルがアプリケーションで実現します。

  1. シークレットの有効期限が切れる 30 日前に、Key Vault から "有効期限が近づいている" ことを示すイベントが Event Grid に発行されます。
  2. Event Grid でイベント サブスクリプションが確認され、HTTP POST を使用して、このイベントをサブスクライブしている関数アプリ エンドポイントが呼び出されます。
  3. 関数アプリによって代替キー (最新ではない方) が特定され、ストレージ アカウントが呼び出されてキーが再生成されます。
  4. 関数アプリによって、再生成された新しいキーが新しいバージョンのシークレットとして Azure Key Vault に追加されます。

前提条件

  • Azure サブスクリプション。 無料で作成できます。
  • Azure Cloud Shell。 このチュートリアルでは、PowerShell 環境でポータル Cloud Shell を使用しています
  • Azure Key Vault。
  • 2 つの Azure ストレージ アカウント。

Note

共有ストレージ アカウント キーのローテーションでは、そのキーに基づいて生成されたアカウント レベルの共有アクセス署名 (SAS) が取り消されます。 ストレージ アカウント キーのローテーション後は、アプリケーションの中断を回避するために、アカウント レベルの SAS トークンを再生成する必要があります。

まだキー コンテナーとストレージ アカウントをお持ちでない場合は、このデプロイ リンクを使用してください。

  1. [リソース グループ] で、 [新規作成] を選択します。 このグループに vault rotation という名前を付けて [OK] を選択します。

  2. [Review + create](レビュー + 作成) を選択します。

  3. [作成] を選択します

    リソース グループの作成方法を示すスクリーンショット。

これで 1 つのキー コンテナーと 2 つのストレージ アカウントが作成されます。 この設定は、Azure CLI または Azure PowerShell でこのコマンドを実行して検証できます。

az resource list -o table -g vaultrotation

結果として得られる出力は次のようになります。

Name                     ResourceGroup         Location    Type                               Status
-----------------------  --------------------  ----------  ---------------------------------  --------
vaultrotation-kv         vaultrotation      westus      Microsoft.KeyVault/vaults
vaultrotationstorage     vaultrotation      westus      Microsoft.Storage/storageAccounts
vaultrotationstorage2    vaultrotation      westus      Microsoft.Storage/storageAccounts

キー ローテーション関数を作成してデプロイする

次に、システム マネージド ID を使用する関数アプリと、その他の必須コンポーネントを作成します。 また、ストレージ アカウント キーのローテーション関数もデプロイします。

関数アプリのローテーション関数には、次のコンポーネントおよび構成が必要です。

  • Azure App Service プラン
  • 関数アプリのトリガーを管理するためのストレージ アカウント
  • Key Vault 内のシークレットにアクセスするためのアクセス ポリシー
  • ストレージ アカウントのアクセス キーにアクセスできるよう関数アプリに割り当てられるストレージ アカウント キー オペレーターのサービス ロール
  • キー ローテーション関数とイベント トリガーおよび HTTP トリガー (オンデマンド ローテーション)
  • SecretNearExpiry イベントの Event Grid イベント サブスクリプション
  1. Azure テンプレートのデプロイのリンクを選択します。

    Azure テンプレートのデプロイのリンク。

  2. [リソース グループ] 一覧から [vaultrotation] を選択します。

  3. [Storage Account RG](ストレージ アカウント RG) ボックスに、自分のストレージ アカウントがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループにストレージ アカウントが既にある場合は、既定値の [resourceGroup().name] のままにしてください。

  4. [ストレージ アカウント名] ボックスに、ローテーションするアクセス キーを含んだストレージ アカウントの名前を入力します。 「前提条件」で作成したストレージ アカウントを使用する場合は、既定値 [concat(resourceGroup().name, 'storage')] をそのまま使用します。

  5. [Key Vault RG](キー コンテナー RG) ボックスに、自分のキー コンテナーがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループに、キー コンテナーが既にある場合は、既定値の [resourceGroup().name] のままにしてください。

  6. [Key Vault 名] ボックスに、キー コンテナーの名前を入力します。 「前提条件」で作成したキー コンテナーを使用する場合は、既定値 [concat(resourceGroup().name, '-kv')] をそのまま使用します。

  7. [App Service Plan Type](App Service プランの種類) ボックスで、ホスティング プランを選択します。 Premium プランは、キー コンテナーがファイアウォールの背後にある場合にのみ必要です。

  8. [関数アプリ名] ボックスに、関数アプリの名前を入力します。

  9. [シークレット名] ボックスに、アクセス キーの保存先となるシークレットの名前を入力します。

  10. [Repo Url](リポジトリの URL) ボックスに、関数コードがある GitHub の場所を入力します。 このチュートリアルでは、https://github.com/Azure-Samples/KeyVault-Rotation-StorageAccountKey-PowerShell.git を使用できます。

  11. [Review + create](レビュー + 作成) を選択します。

  12. [作成] を選択します

    関数を作成してデプロイする方法を示すスクリーンショット。

上記の手順を完了すると、ストレージ アカウント、サーバー ファーム、関数アプリ、Application Insights を使用できるようになります。 デプロイが完了すると、このページが表示されます。

Note

エラーが発生した場合、 [再デプロイ] を選択して、コンポーネントのデプロイを完了できます。

デプロイ テンプレートとローテーション関数のコードは、Azure のサンプルに関するページにあります。

ストレージ アカウントのアクセス キーを Key Vault のシークレットに追加する

まず、シークレットの管理権限をユーザー プリンシパルに付与するようにアクセス ポリシーを設定します。

az keyvault set-policy --upn <email-address-of-user> --name vaultrotation-kv --secret-permissions set delete get list

これで、ストレージ アカウントのアクセス キーを値とする新しいシークレットを作成できます。 さらに、ローテーション関数でストレージ アカウントにキーを再生成できるよう、ストレージ アカウントのリソース ID、シークレットの有効期間、シークレットに追加するキーの ID も必要となります。

ストレージ アカウントのリソース ID を調べます。 この値は、id プロパティで確認できます。

az storage account show -n vaultrotationstorage

キーの値を取得できるよう、ストレージ アカウントのアクセス キーを一覧表示します。

az storage account keys list -n vaultrotationstorage

有効期間を 60 日間に設定し、ストレージ アカウントのリソース ID を指定して、キー コンテナーにシークレットを追加します。また、デモンストレーション用にローテーションを即座にトリガーするために、有効期限を明日に設定します。 取得した key1ValuestorageAccountResourceId の値を使用して、このコマンドを実行します。

tomorrowDate=$(date -u -d "+1 day" +"%Y-%m-%dT%H:%M:%SZ")
az keyvault secret set --name storageKey --vault-name vaultrotation-kv --value <key1Value> --tags "CredentialId=key1" "ProviderAddress=<storageAccountResourceId>" "ValidityPeriodDays=60" --expires $tomorrowDate

このシークレットでは、数分以内に SecretNearExpiry イベントがトリガーされます。 このイベントによって関数がトリガーされ、有効期限が 60 日に設定されたシークレットがローテーションされます。 この構成では、"SecretNearExpiry" イベントが 30 日ごと (有効期限の 30 日前) にトリガーされ、ローテーション関数によって key1 と key2 が交互にローテーションされます。

アクセス キーが再生成されたことは、ストレージ アカウント キーと Key Vault のシークレットを取得して比較することで確認できます。

シークレットの情報を得るには、このコマンドを使用します。

az keyvault secret show --vault-name vaultrotation-kv --name storageKey

CredentialId が代替の keyName に更新され、value が再生成されたことがわかります。

1 つ目のストレージ アカウントに対する A Z keyvault secret show コマンドの出力を示すスクリーンショット。

アクセス キーを取得して値を比較します。

az storage account keys list -n vaultrotationstorage 

キーの value がキー コンテナー内のシークレットと同じであることに注意してください。

1 つ目のストレージ アカウントに対する A Z storage account keys list コマンドの出力を示すスクリーンショット。

複数のストレージ アカウントに既存のローテーション関数を使用する

複数のストレージ アカウントを対象に、同じ関数アプリを再利用してキーのローテーションを行うことができます。

ローテーションするストレージ アカウント キーを既存の関数に追加するには、以下が必要です。

  • ストレージ アカウントのアクセス キーにアクセスできるよう関数アプリに割り当てられるストレージ アカウント キー オペレーターのサービス ロール。
  • SecretNearExpiry イベントの Event Grid イベント サブスクリプション。
  1. Azure テンプレートのデプロイのリンクを選択します。

    Azure テンプレートのデプロイのリンク。

  2. [リソース グループ] 一覧から [vaultrotation] を選択します。

  3. [Storage Account RG](ストレージ アカウント RG) ボックスに、自分のストレージ アカウントがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループにストレージ アカウントが既にある場合は、既定値の [resourceGroup().name] のままにしてください。

  4. [ストレージ アカウント名] ボックスに、ローテーションするアクセス キーを含んだストレージ アカウントの名前を入力します。

  5. [Key Vault RG](キー コンテナー RG) ボックスに、自分のキー コンテナーがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループに、キー コンテナーが既にある場合は、既定値の [resourceGroup().name] のままにしてください。

  6. [Key Vault 名] ボックスに、キー コンテナーの名前を入力します。

  7. [関数アプリ名] ボックスに、関数アプリの名前を入力します。

  8. [シークレット名] ボックスに、アクセス キーの保存先となるシークレットの名前を入力します。

  9. [Review + create](レビュー + 作成) を選択します。

  10. [作成] を選択します

    追加のストレージ アカウントを作成する方法を示すスクリーンショット。

ストレージ アカウントのアクセス キーを Key Vault のシークレットに追加する

ストレージ アカウントのリソース ID を調べます。 この値は、id プロパティで確認できます。

az storage account show -n vaultrotationstorage2

キー 2 の値を取得できるよう、ストレージ アカウントのアクセス キーを一覧表示します。

az storage account keys list -n vaultrotationstorage2

有効期間を 60 日間に設定し、ストレージ アカウントのリソース ID を指定して、キー コンテナーにシークレットを追加します。また、デモンストレーション用にローテーションを即座にトリガーするために、有効期限を明日に設定します。 取得した key2ValuestorageAccountResourceId の値を使用して、このコマンドを実行します。

tomorrowDate=$(date -u -d "+1 day" +"%Y-%m-%dT%H:%M:%SZ")
az keyvault secret set --name storageKey2 --vault-name vaultrotation-kv --value <key2Value> --tags "CredentialId=key2" "ProviderAddress=<storageAccountResourceId>" "ValidityPeriodDays=60" --expires $tomorrowDate

シークレットの情報を得るには、このコマンドを使用します。

az keyvault secret show --vault-name vaultrotation-kv --name storageKey2

CredentialId が代替の keyName に更新され、value が再生成されたことがわかります。

2 つ目のストレージ アカウントに対する A Z keyvault secret show コマンドの出力を示すスクリーンショット。

アクセス キーを取得して値を比較します。

az storage account keys list -n vaultrotationstorage 

キーの value がキー コンテナー内のシークレットと同じであることに注意してください。

2 つ目のストレージ アカウントに対する A Z storage account keys list コマンドの出力を示すスクリーンショット。

シークレットのローテーションを無効にする

シークレットのローテーションは、そのシークレットの Event Grid のサブスクリプションを削除するだけで無効にできます。 Azure PowerShell の Remove-AzEventGridSubscription コマンドレットまたは Azure CLI の az event grid event--subscription delete コマンドを使用します。

2 組の資格情報を使用する Key Vault ローテーション関数

2 組の資格情報用のローテーション関数と、すぐに使用できるいくつかの関数:

Note

これらのローテーション関数は、Microsoft ではなく、コミュニティのメンバーによって作成されています。 コミュニティ機能は、Microsoft サポート プログラムまたはサービスのサポート対象ではなく、"手を加えず" に提供され、いかなる保証もありません。

次のステップ