次の方法で共有


1 セットの認証資格情報を使用するリソースのシークレットのローテーションを自動化する

Azure サービスに対して認証を行う最善の方法は マネージド ID を使用することですが、オプションではないシナリオがいくつかあります。 このような場合は、アクセス キーまたはシークレットが使用されます。 アクセス キーまたはシークレットを定期的にローテーションする必要があります。

このチュートリアルでは、1 セットの認証資格情報を使用するデータベースとサービスのシークレットの定期的なローテーションを自動化する方法について説明します。 さまざまな資産の種類にわたる自動ローテーションの概念と利点の包括的な概要については、「 Azure Key Vault の自動ローテーションについて」を参照してください。

具体的には、このチュートリアルでは、Azure Event Grid 通知によってトリガーされる関数を使用して、Azure Key Vault に格納されている SQL Server パスワードをローテーションします。

回転ソリューションの図

  1. シークレットの有効期限が切れる 30 日前に、Key Vault から "有効期限が近づいている" ことを示すイベントが Event Grid に発行されます。
  2. Event Grid がイベント サブスクリプションを確認し、HTTP POST を使用して、このイベントをサブスクライブしている関数アプリ エンドポイントを呼び出します。
  3. 関数アプリがシークレットの情報を受け取り、新たにランダムなパスワードを生成してから、新しいパスワードを使用して Key Vault にシークレットの新しいバージョンを作成します。
  4. 関数アプリが新しいパスワードを使用して SQL Server を更新します。

手順 3 から 4 の間に遅延が発生する可能性があります。 その間、Key Vault のシークレットは SQL Server に対して認証できません。 いずれかの手順でエラーが発生した場合、Event Grid は 2 時間再試行します。

[前提条件]

既存の Key Vault と SQL Server がない場合は、次のデプロイ リンクを使用できます。

[Deploy to Azure]\(Azure にデプロイ\) というラベルが付けられたボタンが表示されている画像。

  1. [リソース グループ] で、 [新規作成] を選択します。 グループに名前を付けます。このチュートリアルでは akvrotation を使用します。
  2. [ SQL 管理者ログイン] に「SQL 管理者ログイン名」と入力します。
  3. [Review + create](レビュー + 作成) を選択します。
  4. を選択し を作成する

リソース グループを作成する

これで、Key Vault と SQL Server インスタンスが作成されます。 このセットアップは、Azure CLI で次のコマンドを実行して確認できます。

az resource list -o table -g akvrotation

結果は次のような出力になります。

Name                     ResourceGroup         Location    Type                               Status
-----------------------  --------------------  ----------  ---------------------------------  --------
akvrotation-kv           akvrotation      eastus      Microsoft.KeyVault/vaults
akvrotation-sql          akvrotation      eastus      Microsoft.Sql/servers
akvrotation-sql/master   akvrotation      eastus      Microsoft.Sql/servers/databases
akvrotation-sql2         akvrotation      eastus      Microsoft.Sql/servers
akvrotation-sql2/master  akvrotation      eastus      Microsoft.Sql/servers/databases

SQL Server パスワード ローテーション関数を作成してデプロイする

Von Bedeutung

このテンプレートでは、キー コンテナー、SQL Server、Azure 関数が同じリソース グループ内に存在する必要があります。

次に、他の必要なコンポーネントに加えて、システムマネージド ID を持つ関数アプリを作成し、SQL Server パスワード ローテーション関数をデプロイします

関数アプリには、次のコンポーネントが必要です。

  • Azure App Service プラン
  • イベント トリガーと http トリガーを使用した SQL パスワード ローテーション関数を含む関数アプリ
  • 関数アプリのトリガー管理に必要なストレージ アカウント
  • Key Vault 内のシークレットにアクセスするための Function App ID のアクセス ポリシー
  • SecretNearExpiry イベントの Event Grid イベント サブスクリプション
  1. Azure テンプレートのデプロイ リンクを選択します。

    [Deploy to Azure]\(Azure にデプロイ\) というラベルが付けられたボタンが表示されている画像。

  2. リソース グループの一覧で、akvrotation を選択します。

  3. [SQL Server 名] に、ローテーションするパスワードを含む SQL Server 名を入力します

  4. キー ボールト名に、キー ボールト名を入力します。

  5. 関数アプリ名に、関数アプリ名を入力します。

  6. [ シークレット名] に、パスワードが格納されるシークレット名を入力します

  7. リポジトリ URL に、関数コード GitHub の場所を入力します (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)

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

  9. を選択してを作成します。

[確認および作成] を選択します

上記の手順を完了すると、ストレージ アカウント、サーバー ファーム、関数アプリが作成されます。 このセットアップは、Azure CLI で次のコマンドを実行して確認できます。

az resource list -o table -g akvrotation

結果は次の出力のようになります。

Name                     ResourceGroup         Location    Type                               Status
-----------------------  --------------------  ----------  ---------------------------------  --------
akvrotation-kv           akvrotation       eastus      Microsoft.KeyVault/vaults
akvrotation-sql          akvrotation       eastus      Microsoft.Sql/servers
akvrotation-sql/master   akvrotation       eastus      Microsoft.Sql/servers/databases
cfogyydrufs5wazfunctions akvrotation       eastus      Microsoft.Storage/storageAccounts
akvrotation-fnapp        akvrotation       eastus      Microsoft.Web/serverFarms
akvrotation-fnapp        akvrotation       eastus      Microsoft.Web/sites
akvrotation-fnapp        akvrotation       eastus      Microsoft.insights/components

関数アプリを作成し、マネージド ID を使用して Key Vault にアクセスする方法については、「 Azure portal から関数アプリを作成する」、 App Service と Azure Functions のマネージド ID を使用する方法、および Azure portal を使用して Key Vault アクセス ポリシーを割り当てる方法に関するページを参照してください。

回転関数

前の手順の関数でデプロイされたイベントを使用して、Key Vault と SQL データベースを更新してシークレットのローテーションをトリガーします。

関数のトリガー イベント

この関数は、イベント データを読み取り、ローテーション ロジックを実行します。

public static class SimpleRotationEventHandler
{
   [FunctionName("AKVSQLRotation")]
   public static void Run([EventGridTrigger]EventGridEvent eventGridEvent, ILogger log)
   {
      log.LogInformation("C# Event trigger function processed a request.");
      var secretName = eventGridEvent.Subject;
      var secretVersion = Regex.Match(eventGridEvent.Data.ToString(), "Version\":\"([a-z0-9]*)").Groups[1].ToString();
      var keyVaultName = Regex.Match(eventGridEvent.Topic, ".vaults.(.*)").Groups[1].ToString();
      log.LogInformation($"Key Vault Name: {keyVaultName}");
      log.LogInformation($"Secret Name: {secretName}");
      log.LogInformation($"Secret Version: {secretVersion}");

      SecretRotator.RotateSecret(log, secretName, keyVaultName);
   }
}

シークレット ローテーション ロジック

このローテーション メソッドは、シークレットからデータベース情報を読み取り、新しいバージョンのシークレットを作成し、新しいシークレットでデータベースを更新します。

    public class SecretRotator
    {
		private const string CredentialIdTag = "CredentialId";
		private const string ProviderAddressTag = "ProviderAddress";
		private const string ValidityPeriodDaysTag = "ValidityPeriodDays";

		public static void RotateSecret(ILogger log, string secretName, string keyVaultName)
        {
            //Retrieve Current Secret
            var kvUri = "https://" + keyVaultName + ".vault.azure.net";
            var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
            KeyVaultSecret secret = client.GetSecret(secretName);
            log.LogInformation("Secret Info Retrieved");

            //Retrieve Secret Info
            var credentialId = secret.Properties.Tags.ContainsKey(CredentialIdTag) ? secret.Properties.Tags[CredentialIdTag] : "";
            var providerAddress = secret.Properties.Tags.ContainsKey(ProviderAddressTag) ? secret.Properties.Tags[ProviderAddressTag] : "";
            var validityPeriodDays = secret.Properties.Tags.ContainsKey(ValidityPeriodDaysTag) ? secret.Properties.Tags[ValidityPeriodDaysTag] : "";
            log.LogInformation($"Provider Address: {providerAddress}");
            log.LogInformation($"Credential Id: {credentialId}");

            //Check Service Provider connection
            CheckServiceConnection(secret);
            log.LogInformation("Service  Connection Validated");
            
            //Create new password
            var randomPassword = CreateRandomPassword();
            log.LogInformation("New Password Generated");

            //Add secret version with new password to Key Vault
            CreateNewSecretVersion(client, secret, randomPassword);
            log.LogInformation("New Secret Version Generated");

            //Update Service Provider with new password
            UpdateServicePassword(secret, randomPassword);
            log.LogInformation("Password Changed");
            log.LogInformation($"Secret Rotated Successfully");
        }
}

完全なコードは GitHub で確認できます。

Key Vault にシークレットを追加する

アクセス ポリシーを設定して、 管理シークレットの アクセス許可をユーザーに付与します。

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

SQL Server リソース ID、SQL Server ログイン名、シークレットの有効期間 (日数) を含むタグを使用して、新しいシークレットを作成します。 シークレットの名前、SQL データベースの初期パスワード (この例では "Simple123") を指定し、明日に設定されている有効期限を含めます。

$tomorrowDate = (get-date).AddDays(+1).ToString("yyy-MM-ddThh:mm:ssZ")
az keyvault secret set --name sqlPassword --vault-name akvrotation-kv --value "Simple123" --tags "CredentialId=sqlAdmin" "ProviderAddress=<sql-database-resource-id>" "ValidityPeriodDays=90" --expires $tomorrowDate

有効期限が短いシークレットを作成すると、15 分以内に SecretNearExpiry イベントが発行され、シークレットをローテーションする関数がトリガーされます。

テストして検証する

シークレットがローテーションされたことを確認するには、 Key Vault>Secrets に移動します。

Key Vault > シークレットにアクセスする方法を示すスクリーンショット。

sqlPassword シークレットを開き、元のバージョンとローテーションされたバージョンを表示します。

シークレットに移動

Web アプリを作成する

SQL 資格情報を確認するには、Web アプリを作成します。 この Web アプリは、Key Vault からシークレットを取得し、シークレットから SQL データベース情報と資格情報を抽出し、SQL Server への接続をテストします。

Web アプリには、次のコンポーネントが必要です。

  • システムマネージド ID を持つ Web アプリ
  • Web アプリのマネージド ID を介して Key Vault 内のシークレットにアクセスするためのアクセス ポリシー
  1. Azure テンプレートのデプロイ リンクを選択します。

    [Deploy to Azure]\(Azure にデプロイ\) というラベルが付けられたボタンが表示されている画像。

  2. akvrotation リソース グループを選択します。

  3. [SQL Server 名] に、ローテーションするパスワードを含む SQL Server 名を入力します

  4. キー ボールト名に、キー ボールト名を入力します。

  5. [ シークレット名] に、パスワードが格納されているシークレット名を入力します

  6. リポジトリ URL に、Web アプリ コードの GitHub の場所を入力します (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)

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

  8. を選択してを作成します。

Web アプリを開く

デプロイされたアプリケーション URL に移動します。

https://akvrotation-app.azurewebsites.net/

ブラウザーでアプリケーションが開くと、[ 生成されたシークレット値 ] と [ データベース接続 済み] の値が true と表示されます。

詳細情報