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

Azure サービスに対して認証する最善の方法はマネージド ID を使用することですが、一部のシナリオではアクセス キー、パスワード、またはその他のシークレットが必要です。 これらのシークレットを定期的にローテーションして、漏洩した資格情報の影響を軽減します。

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

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

Tip

Azure SQL DatabaseとAzure SQL Managed Instanceの場合は、SQL ログインよりもMicrosoft Entra専用認証を使用します。 このチュートリアルでは、ワークロードで SQL 認証が必要な場合にのみ、パスワードローテーション パターンを使用します。

回転ソリューションの図

  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 時間再試行します。

[前提条件]

  • Azure サブスクリプション - 無料で作成
  • Azure Key Vault。
  • SQL Server。

キー コンテナーと SQL Server インスタンスがまだない場合は、次のデプロイ リンクを使用します。

「Deploy to Azure」とラベル付けされたボタンが表示されている画像

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

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

これで、キー コンテナーと 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 インスタンス、関数アプリが同じリソース グループ内に存在する必要があります。

次に、システム割り当てマネージド ID とその他の必要なコンポーネントを含む関数アプリを作成し、SQL Serverパスワード ローテーション関数をデプロイします。

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

  • Azure App Service プラン。
  • Event Grid トリガーと HTTP トリガーを持つ SQL パスワード ローテーション関数を持つ関数アプリ。
  • 関数アプリトリガー管理のストレージ アカウント。
  • Function App の ID が Key Vault 内のシークレットにアクセスできるようにする Azure ロールの割り当て。
  • SecretNearExpiry イベントの Event Grid イベント サブスクリプション。
  1. Azure テンプレートのデプロイ リンクを選択します。

    「Deploy to Azure」とラベル付けされたボタンが表示されている画像

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

  3. [SQL Server名] に、パスワードをローテーションするSQL Server インスタンスの名前を入力します。

  4. Key Vault Name で、キー コンテナー名を入力します。

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

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

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

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

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

この ARM テンプレートでは、App Service ソース管理 (Kudu) デプロイを使用して、GitHubから関数コードをプルします。 本番ワークロードには、func azure functionapp publishWEBSITE_RUN_FROM_PACKAGE を使用した zip デプロイ などのパッケージベースのデプロイをお勧めします。

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

前の手順を完了すると、ストレージ アカウント、サーバー ファーム、関数アプリが作成されます。 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 ポータルから関数アプリを作成する」、App Service と Azure Functions のマネージド ID を使用する方法、Azure RBAC を使用したKey Vaultへのアクセスを提供する方法に関するページを参照してください。

サンプル関数は、Azure Functionsの.NETインプロセス モデルを対象としています。 新しい開発では、.NET分離ワーカー モデルを使用します。これは、今後サポートされるモデルです。

回転関数

前の手順でデプロイした関数は、イベントを使用してシークレットのローテーションをトリガーします。 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に追加する

Key Vault のシークレットを管理できるように、Key Vault Secrets Officer ロールを自分に割り当ててください。

az role assignment create --role "Key Vault Secrets Officer" --assignee <email-address-of-user> --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/akvrotation-kv

SQL Server リソース ID、SQL Server ログイン名、シークレットの有効期間 (日数) を含むタグを含むシークレットを作成します。 シークレット名、SQL データベースの初期パスワード (この例ではSimple123 )、有効期限を明日に設定して、ローテーションがすぐにトリガーされるように設定します。

tomorrowDate=$(date -u -d "+1 day" +"%Y-%m-%dT%H:%M:%SZ")
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 Secrets にアクセスする方法を示すスクリーンショット

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

シークレットに移動

Web アプリを作成する

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

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

  • システム割り当てマネージド ID を持つ Web アプリ。
  • Web アプリのマネージド ID がキー コンテナー内のシークレットを読み取れるロールの割り当て。
  1. Azure テンプレートのデプロイ リンクを選択します。

    「Deploy to Azure」とラベル付けされたボタンが表示されている画像

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

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

  4. Key Vault Name にキー コンテナー名を入力します。

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

  6. [Repo URL]\(リポジトリ 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ページに表示されます。

AI を使用してデータベースのローテーション関数をカスタマイズする

このチュートリアルでは、SQL Serverのシークレット ローテーションについて説明しますが、他のデータベースの種類に合わせてローテーション関数を調整できます。 GitHub Copilotは、データベースまたは資格情報の種類で動作するようにローテーション関数コードを変更するのに役立ちます。

I'm using the Azure Key Vault secret rotation tutorial for SQL Server. Help me modify the rotation function to work with PostgreSQL instead. The function should:
1. Generate a new secure password
2. Update the PostgreSQL database user password
3. Store the new password in Key Vault
Show me the changes needed to the C# function code, including the correct PostgreSQL connection library and password update command.

Copilotは、API キー、接続文字列、サービス アカウント パスワードなどの他の資格情報の種類にこのパターンを適応させるのにも役立ちます。

GitHub Copilotは AI を活用しているため、驚きや間違いが起こりうる可能性があります。 詳細については、Copilot FAQ を参照してください。

詳細情報