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

A melhor forma de autenticar nos serviços do Azure é através de uma identidade gerida, mas existem alguns cenários em que isso não é uma opção. Nesses casos, são utilizadas chaves de acesso ou segredos. Deve rodar periodicamente chaves de acesso ou segredos.

Este tutorial mostra como automatizar a rotação periódica de segredos para bases de dados e serviços que utilizam um conjunto de credenciais de autenticação. Especificamente, este tutorial roda SQL Server palavras-passe armazenadas no Azure Key Vault através de uma função acionada por Azure Event Grid notificação:

Diagrama da solução de rotação

  1. Trinta dias antes da data de expiração de um segredo, Key Vault publica o evento "quase expiração" no Event Grid.
  2. O Event Grid verifica as subscrições de eventos e utiliza HTTP POST para chamar o ponto final da aplicação de funções subscrito ao evento.
  3. A aplicação de funções recebe as informações secretas, gera uma nova palavra-passe aleatória e cria uma nova versão para o segredo com a nova palavra-passe no Key Vault.
  4. A aplicação de funções atualiza SQL Server com a nova palavra-passe.

Nota

Pode haver um atraso entre os passos 3 e 4. Durante esse período, o segredo no Key Vault não poderá autenticar-se no SQL Server. Em caso de falha de qualquer um dos passos, o Event Grid volta a tentar durante duas horas.

Pré-requisitos

Se não tiver Key Vault e SQL Server existentes, pode utilizar esta ligação de implementação:

Imagem a mostrar um botão com o nome

  1. Em Grupo de recursos, selecione Criar novo. Atribua um nome ao grupo, utilizamos akvrotation neste tutorial.
  2. Em Início de Sessão do SQL Administração, escreva nome de início de sessão do administrador do SQL.
  3. Selecione Rever + criar.
  4. Selecione Criar

Criar um grupo de recursos

Terá agora uma Key Vault e uma instância de SQL Server. Pode verificar esta configuração na CLI do Azure ao executar o seguinte comando:

az resource list -o table -g akvrotation

O resultado irá procurar algo no seguinte resultado:

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 implementar a função de rotação de palavras-passe do SQL Server

Importante

Este modelo requer que o cofre de chaves, o SQL Server e a Função do Azure estejam no mesmo grupo de recursos.

Em seguida, crie uma aplicação de funções com uma identidade gerida pelo sistema, para além dos outros componentes necessários, e implemente funções de rotação de palavras-passe do SQL Server

A aplicação de funções requer estes componentes:

  • Um plano de Serviço de Aplicações do Azure
  • Uma Aplicação de Funções com funções de rotação de palavras-passe SQL com acionador de eventos e acionador http
  • Uma conta de armazenamento necessária para a gestão de acionadores da aplicação de funções
  • Uma política de acesso para a identidade da Aplicação de Funções aceder a segredos no Key Vault
  • Uma subscrição de evento do Event Grid para o evento SecretNearExpiry
  1. Selecione a ligação de implementação de modelos do Azure:

    Imagem a mostrar um botão com o nome

  2. Na lista Grupo de recursos, selecione akvrotation.

  3. No Nome do SQL Server, escreva o nome do SQL Server com a palavra-passe para rodar

  4. No nome do Key Vault, escreva o nome do cofre de chaves

  5. No Nome da Aplicação de Funções, escreva o nome da aplicação de funções

  6. No Nome do Segredo, escreva o nome do segredo onde a palavra-passe será armazenada

  7. No Url do Repositório, escreva código de função Localização do GitHub (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git)

  8. Selecione Rever + criar.

  9. Selecione Criar.

Selecione Rever+criar

Depois de concluir os passos anteriores, terá uma conta de armazenamento, um farm de servidores e uma aplicação de funções. Pode verificar esta configuração na CLI do Azure ao executar o seguinte comando:

az resource list -o table -g akvrotation

O resultado terá um aspeto semelhante ao seguinte resultado:

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 uma aplicação de funções e utilizar a identidade gerida para aceder a Key Vault, consulte Criar uma aplicação de funções a partir do portal do Azure, Como utilizar a identidade gerida para Serviço de Aplicações e Funções do Azure e Atribuir uma Key Vault política de acesso com o portal do Azure.

Função rotação

Implementado na função passo anterior utiliza um evento para acionar a rotação de um segredo ao atualizar Key Vault e a base de dados SQL.

Evento do acionador de funções

Esta função lê os dados do evento 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 secreta

Este método de rotação lê as informações da base de dados do segredo, cria uma nova versão do segredo e atualiza a base de dados com o 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");
        }
}

Pode encontrar o código completo no GitHub.

Adicionar o segredo ao Key Vault

Defina a sua política de acesso para conceder permissões de gestão de segredos aos utilizadores:

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

Crie um novo segredo com etiquetas que contenham o ID de recurso SQL Server, o nome de início de sessão SQL Server e o período de validade do segredo em dias. Indique o nome do segredo, palavra-passe inicial da base de dados SQL (no nosso exemplo "Simple123") e inclua uma data de expiração 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 expiração curta irá publicar um SecretNearExpiry evento dentro de 15 minutos, o que, por sua vez, irá acionar a função para rodar o segredo.

Testar e verificar

Para verificar se o segredo rodou, aceda a Key Vault>Secrets:

Captura de ecrã que mostra como aceder a segredos Key Vault>.

Abra o segredo sqlPassword e veja as versões originais e rotativas:

Ir para Segredos

Criar uma aplicação Web

Para verificar as credenciais do SQL, crie uma aplicação Web. Esta aplicação Web obterá o segredo de Key Vault, extrairá as informações e credenciais da base de dados SQL do segredo e testará a ligação ao SQL Server.

A aplicação Web requer estes componentes:

  • Uma aplicação Web com identidade gerida pelo sistema
  • Uma política de acesso para aceder a segredos no Key Vault através da identidade gerida da aplicação Web
  1. Selecione a ligação de implementação de modelos do Azure:

    Imagem a mostrar um botão com o nome

  2. Selecione o grupo de recursos akvrotation .

  3. No Nome do SQL Server, escreva o nome do SQL Server com a palavra-passe para rodar

  4. No nome do Key Vault, escreva o nome do cofre de chaves

  5. No Nome do Segredo, escreva o nome do segredo onde a palavra-passe está armazenada

  6. No Url do Repositório, escreva a localização do GitHub do código da aplicação Web (https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git)

  7. Selecione Rever + criar.

  8. Selecione Criar.

Abrir a aplicação Web

Aceda ao URL da aplicação implementada:

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

Quando a aplicação abrir no browser, verá o Valor do Segredo Gerado e um valor Ligado à Base de Dados verdadeiro.

Saber mais