Automatizar a rotação de um segredo para recursos que usam um conjunto de credenciais de autenticação

A melhor maneira de se autenticar nos serviços do Azure é usando uma identidade gerenciada, mas há alguns cenários em que essa não é uma opção. Nesses casos, são usadas chaves de acesso ou segredos. Você deve realizar periodicamente a rotação de chaves de acesso ou segredos.

Este tutorial mostra como automatizar a rotação periódica de segredos para bancos de dados e serviços que usam um conjunto de credenciais de autenticação. Especificamente, este tutorial realiza a rotação das senhas do SQL Server armazenadas no Azure Key Vault usando uma função disparada pela notificação da Grade de Eventos do Azure:

Diagrama de solução de rotação

  1. Trinta dias antes da data de validade de um segredo, o Key Vault publica o evento de "expiração próxima" na Grade de Eventos.
  2. A Grade de Eventos verifica as assinaturas de eventos e usa HTTP POST para chamar o ponto de extremidade do aplicativo de funções assinado para o evento.
  3. O aplicativo de funções recebe as informações secretas, gera uma nova senha aleatória e cria uma versão para o segredo com a nova senha no Key Vault.
  4. O aplicativo de funções atualiza o SQL Server com uma nova senha.

Observação

Pode haver um atraso entre as etapas 3 e 4. Durante esse tempo, o segredo no Key Vault não poderá se autenticar no SQL Server. Em caso de uma falha em qualquer uma das etapas, a Grade de Eventos realiza novas tentativas por duas horas.

Pré-requisitos

Se você não tiver um Key Vault nem um SQL Server existente, poderá usar este link de implantação:

Imagem mostrando um botão rotulado como

  1. Em Grupo de recursos, selecione Criar. Dê um nome ao grupo, neste tutorial usamos akvrotation.
  2. Em Logon do Administrador do SQL, digite a ID de logon do administrador do SQL.
  3. Selecione Examinar + criar.
  4. Escolha Criar

Criar um grupo de recursos

Agora você terá um Key Vault e uma instância do SQL Server. Você pode verificar essa configuração na CLI do Azure executando o seguinte comando:

az resource list -o table -g akvrotation

O resultado terá uma aparência semelhante à da seguinte saída:

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

Criar e implantar função de rotação de senha do SQL Server

Importante

Este modelo exige que o Key Vault, o SQL Server e a Função do Azure estejam no mesmo grupo de recursos

Em seguida, crie um aplicativo de funções com uma identidade gerenciada pelo sistema, juntamente com os outros componentes necessários e implante as funções de rotação de senha do SQL Server

O aplicativo de funções requer estes componentes:

  • Um plano do Serviço de Aplicativo do Azure
  • Um Aplicativo de Funções com funções de rotação de senha do SQL com gatilho de evento e gatilho http
  • Uma conta de armazenamento necessária para o gerenciamento de gatilho do aplicativo de funções
  • Uma política de acesso para usar a identidade do Aplicativo de Funções para acessar segredos no Key Vault
  • Assinatura de evento da Grade de Eventos para o evento SecretNearExpiry
  1. Selecione o link de implantação de modelo do Azure:

    Imagem mostrando um botão rotulado como

  2. Na lista Grupo de recursos, selecione akvrotation.

  3. No Nome do SQL Server, digite o nome do SQL Server com a senha para rotação

  4. No Nome do Cofre de Chaves, digite o nome do cofre de chaves

  5. No Nome do Aplicativo de Funções, digite o nome do aplicativo de funções

  6. No Nome do Segredo, digite o nome do segredo em que a senha será armazenada

  7. Na URL do Repositório, digite a localização do GitHub do código de função (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)

  8. Selecione Examinar + criar.

  9. Selecione Criar.

Selecione Examinar + criar

Depois de concluir as etapas anteriores, você terá uma conta de armazenamento, um farm de servidores e um aplicativo de funções. Você pode verificar essa configuração na CLI do Azure executando o seguinte comando:

az resource list -o table -g akvrotation

O resultado terá uma aparência semelhante à da seguinte saída:

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

Para obter informações sobre como criar um aplicativo de funções e usar a identidade gerenciada para acessar o Key Vault, confira Criar um aplicativo de funções no portal do Azure, Como usar identidades gerenciadas para o Serviço de Aplicativo e o Azure Functions e Atribuir uma política de acesso do Key Vault usando o portal do Azure.

Função de rotação

A função implantada na etapa anterior usa um evento para disparar a rotação de um segredo atualizando o Key Vault e o Banco de Dados SQL.

Evento de gatilho de função

Essa função lê dados de eventos e executa a lógica de rotação:

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);
   }
}

Lógica de rotação do segredo

Esse método de rotação lê as informações do banco de dados do segredo, cria uma versão do segredo e atualiza o banco de dados com um novo segredo:

    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");
        }
}

É possível encontrar o código de exemplo no GitHub.

Adicionar o segredo ao Key Vault

Defina sua política de acesso para conceder as permissões para gerenciar segredos a usuários:

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

Crie um segredo com marcas que contenham a ID de recurso do SQL Server, o nome de logon do SQL Server e o período de validade do segredo em dias. Forneça o nome do segredo, a senha inicial do Banco de Dados SQL (em nosso exemplo "Simple123") e inclua uma data de validade definida para amanhã.

$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

A criação de um segredo com uma data de validade curta publicará um evento SecretNearExpiry em 15 minutos, o que, por sua vez, disparará a função para realizar a rotação do segredo.

Testar e verificar

Para verificar se a rotação do segredo foi realizada, acesse Key Vault>Segredos:

Captura de tela que mostra como acessar Key Vault > Segredos.

Abra o segredo sqlPassword e veja as versões originais e com rotação:

Acessar Segredos

Criar um aplicativo Web

Para verificar as credenciais do SQL, crie um aplicativo Web. Esse aplicativo Web obterá o segredo do Key Vault, extrairá as informações e as credenciais do Banco de Dados SQL do segredo e testará a conexão com o SQL Server.

O aplicativo Web requer estes componentes:

  • Um aplicativo Web com identidade gerenciada pelo sistema
  • Uma política de acesso para acessar segredos no Key Vault usando a identidade gerenciada do aplicativo Web
  1. Selecione o link de implantação de modelo do Azure:

    Imagem mostrando um botão rotulado como

  2. Selecione o grupo de recursos akvrotation.

  3. No Nome do SQL Server, digite o nome do SQL Server com a senha para rotação

  4. No Nome do Cofre de Chaves, digite o nome do cofre de chaves

  5. No Nome do Segredo, digite o nome do segredo no qual a senha está armazenada

  6. Na URL do Repositório, digite a localização do GitHub do código do aplicativo Web (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)

  7. Selecione Examinar + criar.

  8. Selecione Criar.

Abra o aplicativo Web

Acesse a URL de aplicativo implantado:

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

Quando o aplicativo for aberto no navegador, você verá o Valor Secreto Gerado e um valor de Banco de Dados Conectado igual a verdadeiro.

Saiba mais