2 セットの認証資格情報があるリソースを対象にシークレットのローテーションを自動化する
Azure サービスに対する認証を行う最善の方法はマネージド ID を使用することですが、この方法を選択できないシナリオもあります。 このような場合は、アクセス キーまたはパスワードが使用されます。 アクセス キーとパスワードは頻繁にローテーションする必要があります。
このチュートリアルでは、2 セットの認証資格情報を使用するデータベースとサービスを対象に、シークレットの定期的なローテーションを自動化する方法について説明します。 具体的には、Azure Key Vault にシークレットとして格納されている Azure ストレージ アカウント キーをローテーションする方法について説明します。 Azure Event Grid の通知によってトリガーされる関数を使用します。
Note
ストレージ アカウント サービスの場合は、Microsoft Entra ID を使用して要求を承認することをお勧めします。 詳しくは、Microsoft Entra ID を使用した BLOB へのアクセスの認可に関する記事をご覧ください。 アクセス キーと共にストレージ アカウントの接続文字列を必要とするサービスがあります。 そのようなシナリオで、このソリューションは推奨されます。
このチュートリアルで説明するローテーション ソリューションを次に示します。
このソリューションでは、ストレージ アカウントの個々のアクセス キーが、同じシークレットの別バージョンとして Azure Key Vault に格納され、プライマリとセカンダリのキーが後続のバージョンで交互に入れ替わります。 最新バージョンのシークレットにアクセス キーが格納されるときは、代替キーが再生成されて、新たな最新バージョンのシークレットとして Key Vault に追加されます。 このソリューションによって、再生成された最新のキーに更新するための完全なローテーション サイクルがアプリケーションで実現します。
- シークレットの有効期限が切れる 30 日前に、Key Vault から "有効期限が近づいている" ことを示すイベントが Event Grid に発行されます。
- Event Grid でイベント サブスクリプションが確認され、HTTP POST を使用して、このイベントをサブスクライブしている関数アプリ エンドポイントが呼び出されます。
- 関数アプリによって代替キー (最新ではない方) が特定され、ストレージ アカウントが呼び出されてキーが再生成されます。
- 関数アプリによって、再生成された新しいキーが新しいバージョンのシークレットとして Azure Key Vault に追加されます。
前提条件
- Azure サブスクリプション。 無料で作成できます。
- Azure Cloud Shell。 このチュートリアルでは、PowerShell 環境でポータル Cloud Shell を使用しています
- Azure Key Vault。
- 2 つの Azure ストレージ アカウント。
Note
共有ストレージ アカウント キーのローテーションでは、そのキーに基づいて生成されたアカウント レベルの共有アクセス署名 (SAS) が取り消されます。 ストレージ アカウント キーのローテーション後は、アプリケーションの中断を回避するために、アカウント レベルの SAS トークンを再生成する必要があります。
まだキー コンテナーとストレージ アカウントをお持ちでない場合は、このデプロイ リンクを使用してください。
[リソース グループ] で、 [新規作成] を選択します。 このグループに vault rotation という名前を付けて [OK] を選択します。
[Review + create](レビュー + 作成) を選択します。
[作成] を選択します
これで 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 イベント サブスクリプション
Azure テンプレートのデプロイのリンクを選択します。
[リソース グループ] 一覧から [vaultrotation] を選択します。
[Storage Account RG](ストレージ アカウント RG) ボックスに、自分のストレージ アカウントがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループにストレージ アカウントが既にある場合は、既定値の [resourceGroup().name] のままにしてください。
[ストレージ アカウント名] ボックスに、ローテーションするアクセス キーを含んだストレージ アカウントの名前を入力します。 「前提条件」で作成したストレージ アカウントを使用する場合は、既定値 [concat(resourceGroup().name, 'storage')] をそのまま使用します。
[Key Vault RG](キー コンテナー RG) ボックスに、自分のキー コンテナーがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループに、キー コンテナーが既にある場合は、既定値の [resourceGroup().name] のままにしてください。
[Key Vault 名] ボックスに、キー コンテナーの名前を入力します。 「前提条件」で作成したキー コンテナーを使用する場合は、既定値 [concat(resourceGroup().name, '-kv')] をそのまま使用します。
[App Service Plan Type](App Service プランの種類) ボックスで、ホスティング プランを選択します。 Premium プランは、キー コンテナーがファイアウォールの背後にある場合にのみ必要です。
[関数アプリ名] ボックスに、関数アプリの名前を入力します。
[シークレット名] ボックスに、アクセス キーの保存先となるシークレットの名前を入力します。
[Repo Url](リポジトリの URL) ボックスに、関数コードがある GitHub の場所を入力します。 このチュートリアルでは、https://github.com/Azure-Samples/KeyVault-Rotation-StorageAccountKey-PowerShell.git を使用できます。
[Review + create](レビュー + 作成) を選択します。
[作成] を選択します
上記の手順を完了すると、ストレージ アカウント、サーバー ファーム、関数アプリ、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 を指定して、キー コンテナーにシークレットを追加します。また、デモンストレーション用にローテーションを即座にトリガーするために、有効期限を明日に設定します。 取得した key1Value
と storageAccountResourceId
の値を使用して、このコマンドを実行します。
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
が再生成されたことがわかります。
アクセス キーを取得して値を比較します。
az storage account keys list -n vaultrotationstorage
キーの value
がキー コンテナー内のシークレットと同じであることに注意してください。
複数のストレージ アカウントに既存のローテーション関数を使用する
複数のストレージ アカウントを対象に、同じ関数アプリを再利用してキーのローテーションを行うことができます。
ローテーションするストレージ アカウント キーを既存の関数に追加するには、以下が必要です。
- ストレージ アカウントのアクセス キーにアクセスできるよう関数アプリに割り当てられるストレージ アカウント キー オペレーターのサービス ロール。
- SecretNearExpiry イベントの Event Grid イベント サブスクリプション。
Azure テンプレートのデプロイのリンクを選択します。
[リソース グループ] 一覧から [vaultrotation] を選択します。
[Storage Account RG](ストレージ アカウント RG) ボックスに、自分のストレージ アカウントがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループにストレージ アカウントが既にある場合は、既定値の [resourceGroup().name] のままにしてください。
[ストレージ アカウント名] ボックスに、ローテーションするアクセス キーを含んだストレージ アカウントの名前を入力します。
[Key Vault RG](キー コンテナー RG) ボックスに、自分のキー コンテナーがあるリソース グループの名前を入力します。 キー ローテーション関数のデプロイ先と同じリソース グループに、キー コンテナーが既にある場合は、既定値の [resourceGroup().name] のままにしてください。
[Key Vault 名] ボックスに、キー コンテナーの名前を入力します。
[関数アプリ名] ボックスに、関数アプリの名前を入力します。
[シークレット名] ボックスに、アクセス キーの保存先となるシークレットの名前を入力します。
[Review + create](レビュー + 作成) を選択します。
[作成] を選択します
ストレージ アカウントのアクセス キーを Key Vault のシークレットに追加する
ストレージ アカウントのリソース ID を調べます。 この値は、id
プロパティで確認できます。
az storage account show -n vaultrotationstorage2
キー 2 の値を取得できるよう、ストレージ アカウントのアクセス キーを一覧表示します。
az storage account keys list -n vaultrotationstorage2
有効期間を 60 日間に設定し、ストレージ アカウントのリソース ID を指定して、キー コンテナーにシークレットを追加します。また、デモンストレーション用にローテーションを即座にトリガーするために、有効期限を明日に設定します。 取得した key2Value
と storageAccountResourceId
の値を使用して、このコマンドを実行します。
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
が再生成されたことがわかります。
アクセス キーを取得して値を比較します。
az storage account keys list -n vaultrotationstorage
キーの value
がキー コンテナー内のシークレットと同じであることに注意してください。
シークレットのローテーションを無効にする
シークレットのローテーションは、そのシークレットの Event Grid のサブスクリプションを削除するだけで無効にできます。 Azure PowerShell の Remove-AzEventGridSubscription コマンドレットまたは Azure CLI の az event grid event--subscription delete コマンドを使用します。
2 組の資格情報を使用する Key Vault ローテーション関数
2 組の資格情報用のローテーション関数と、すぐに使用できるいくつかの関数:
Note
これらのローテーション関数は、Microsoft ではなく、コミュニティのメンバーによって作成されています。 コミュニティ機能は、Microsoft サポート プログラムまたはサービスのサポート対象ではなく、"手を加えず" に提供され、いかなる保証もありません。