Automatizzare la rotazione di un segreto per le risorse che usano un set di credenziali di autenticazione

Il modo migliore per eseguire l'autenticazione per Azure servizi è con un'identità gestita, ma alcuni scenari richiedono una chiave di accesso, una password o un altro segreto. Ruotare regolarmente tali segreti per ridurre l'impatto di una credenziale persa.

Questa esercitazione illustra come automatizzare la rotazione periodica dei segreti per database e servizi che usano un set di credenziali di autenticazione. Per una panoramica dell'autorotazione in diversi tipi di asset, vedere Informazioni sull'autorotazione in Azure Key Vault.

In particolare, questa esercitazione ruota una password SQL Server archiviata in Azure Key Vault usando una funzione attivata da una notifica di Griglia di eventi di Azure:

Suggerimento

Per database SQL di Azure e Istanza gestita di SQL di Azure, preferisci l'autenticazione esclusiva con Microsoft Entra rispetto agli account SQL. Usare il modello di rotazione delle password in questa esercitazione solo quando un carico di lavoro richiede l'autenticazione SQL.

Diagramma della soluzione di rotazione

  1. Trenta giorni prima della data di scadenza di un segreto, Key Vault pubblica l'evento "near expiry" in Griglia di eventi.
  2. Griglia di eventi controlla le sottoscrizioni di eventi e, tramite POST HTTP, chiama l'endpoint app per le funzioni che ha sottoscritto questo evento.
  3. L'app per le funzioni riceve le informazioni segrete, genera una nuova password casuale e crea una nuova versione per il segreto con la nuova password in Key Vault.
  4. L'app per le funzioni aggiorna SQL Server con la nuova password.

Annotazioni

Può verificarsi un ritardo tra i passaggi 3 e 4. Durante tale intervallo, il segreto in Key Vault non può essere usato per autenticarsi con SQL Server. Se un passaggio ha esito negativo, Event Grid esegue nuovi tentativi per due ore.

Prerequisiti

Se non si ha già un insieme di credenziali e un'istanza di SQL Server, usare questo link di distribuzione:

Image che mostra un pulsante con l'etichetta

  1. In Gruppo di risorse selezionare Crea nuovo e assegnare un nome al gruppo. Questo tutorial usa akvrotation.
  2. In Accesso amministratore SQL, immettere il nome di accesso dell'amministratore SQL.
  3. Selezionare Rivedi e crea.
  4. Fare clic su Crea.

Creare un gruppo di risorse

A questo punto saranno disponibili un'istanza dell'insieme di credenziali delle chiavi e una di SQL Server. Verificare questa configurazione nel interfaccia della riga di comando di Azure:

az resource list -o table -g akvrotation

Il risultato è simile all'output seguente:

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

Creare e distribuire la funzione di rotazione delle password SQL Server

Importante

Questo modello richiede che l'insieme di credenziali, l'istanza di SQL Server e l'app per funzioni si trovino nello stesso gruppo di risorse.

Creare quindi un'app per le funzioni con un'identità gestita assegnata dal sistema insieme agli altri componenti necessari e distribuire la funzione di rotazione delle password SQL Server.

L'app per le funzioni richiede questi componenti:

  • Un piano di servizio app di Azure.
  • Un'app per funzioni con una funzione di rotazione della password SQL che include un trigger di Event Grid e un trigger HTTP.
  • Un account di archiviazione usato per la gestione dei trigger dell'app per le funzioni.
  • Assegnazione di ruolo di Azure che consente all'identità dell'app per le funzioni di accedere ai segreti nell'insieme di credenziali delle chiavi.
  • Sottoscrizione a un evento Event Grid per l'evento SecretNearExpiry.
  1. Selezionare il collegamento di distribuzione del modello di Azure:

    Image che mostra un pulsante con l'etichetta

  2. Nell'elenco Gruppo di risorse selezionare akvrotation.

  3. In SQL Server Nome immettere il nome dell'istanza di SQL Server la cui password si desidera ruotare.

  4. In Nome dell'insieme di credenziali delle chiavi immettere il nome dell'insieme di credenziali delle chiavi.

  5. In Nome dell'app per le funzioni, immettere il nome dell'app per le funzioni.

  6. In Nome segreto, immetti il nome del segreto che memorizza la password.

  7. In URL del repository, inserisci la posizione su GitHub del codice della funzione: https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp.git.

  8. Selezionare Rivedi e crea.

  9. Fare clic su Crea.

Annotazioni

Questo modello ARM usa la distribuzione tramite controllo del codice sorgente di App Service (Kudu) per recuperare il codice della funzione da GitHub. Per un carico di lavoro in produzione, consigliamo invece una distribuzione basata su pacchetto, ad esempio func azure functionapp publish o zip deploy con WEBSITE_RUN_FROM_PACKAGE.

Selezionare Rivedi e crea.

Dopo aver completato i passaggi precedenti, si dispone di un account di archiviazione, di una server farm e di un'app per le funzioni. Verificare questa configurazione nel interfaccia della riga di comando di Azure:

az resource list -o table -g akvrotation

Il risultato è simile all'output seguente:

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

Per altre informazioni su come creare un'app per funzioni e utilizzare un'identità gestita per accedere a Key Vault, vedere Creare un'app per funzioni dal portale di Azure, Come usare l'identità gestita per App Service e Funzioni di Azure e Fornire l'accesso a Key Vault con Azure RBAC.

Annotazioni

La funzione di esempio è destinata al modello in-process .NET per Funzioni di Azure. Per il nuovo sviluppo, usare il modello di lavoro isolato .NET, che è il modello supportato in futuro.

Funzione di Rotazione

La funzione implementata nel passaggio precedente usa un evento per attivare la rotazione dei segreti. Aggiorna Key Vault e il database SQL.

Evento di attivazione della funzione

Questa funzione legge i dati dell'evento ed esegue la logica di rotazione:

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

Logica di rotazione del segreto

Questo metodo di rotazione legge le informazioni del database dal segreto, crea una nuova versione del segreto e aggiorna il database con il nuovo segreto:

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

Il codice completo è disponibile in GitHub.

Aggiungere il segreto a Key Vault

Assegnare a sé stessi il ruolo Key Vault Secrets Officer in modo da poter gestire i segreti nell'insieme di credenziali:

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

Creare un segreto con tag che contengono l'ID risorsa SQL Server, il nome di accesso SQL Server e il periodo di validità del segreto in giorni. Impostare il nome del segreto, la password iniziale dal database SQL (Simple123 in questo esempio) e una data di scadenza impostata su domani in modo che la rotazione venga attivata immediatamente.

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

L'impostazione di una data di scadenza breve pubblica un SecretNearExpiry evento entro 15 minuti, che attiva la funzione per ruotare il segreto.

Prova e verifica

Per verificare che il segreto sia stato ruotato, vai a Key Vault>Segreti:

Screenshot che illustra come accedere a Key Vault > Secrets.

Aprire il segreto sqlPassword e visualizzare le versioni originali e ruotate:

Passare a segreti

Creare un'app Web

Per verificare le credenziali SQL, creare un'app Web. L'app Web recupera il segreto da Key Vault, estrae le informazioni e le credenziali del database SQL dal segreto e testa la connessione a SQL Server.

L'app Web richiede questi componenti:

  • Un'app Web con un'identità gestita assegnata dal sistema.
  • Un'assegnazione di ruolo che consente all'identità gestita dell'app Web di leggere i segreti nell'insieme di credenziali delle chiavi.
  1. Selezionare il collegamento di distribuzione del modello di Azure:

    Image che mostra un pulsante con l'etichetta

  2. Selezionare il gruppo di risorse akvrotation .

  3. In Nome del server SQL, immetti il nome del server SQL di cui hai modificato la password.

  4. In Nome dell'insieme di credenziali delle chiavi immettere il nome dell'insieme di credenziali delle chiavi.

  5. In Nome segreto, immetti il nome del segreto che memorizza la password.

  6. Nel campo URL del repository, immetti l'indirizzo GitHub del codice dell'app web: https://github.com/Azure-Samples/KeyVault-Rotation-SQLPassword-Csharp-WebApp.git.

  7. Selezionare Rivedi e crea.

  8. Fare clic su Crea.

Aprire l'app Web

Passare all'URL dell'applicazione distribuita: https://akvrotation-app.azurewebsites.net/.

Quando l'applicazione viene aperta nel browser, nella pagina vengono visualizzati il valore del segreto generato e il valore database connesso di true.

Usare l'intelligenza artificiale per personalizzare la funzione di rotazione per il database

Questa esercitazione illustra la rotazione dei segreti per SQL Server, ma è possibile adattare la funzione di rotazione per altri tipi di database. GitHub Copilot consente di modificare il codice della funzione di rotazione in modo che funzioni con il database o il tipo di credenziale.

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 consente anche di adattare questo modello per altri tipi di credenziali, ad esempio chiavi API, stringhe di connessione o password dell'account del servizio.

GitHub Copilot è basato sull'IA, quindi sono possibili sorprese ed errori. Per altre informazioni, vedere Copilot domande frequenti.

Ulteriori informazioni