Uso di Azure Key Vault per mantenere i segreti fuori dal codice sorgente dell'app Web

Uso di Azure Key Vault per mantenere i segreti fuori dal codice sorgente dell'app Web

In vista del Bootcamp globale di Azure, ho cercato come consentire a un team distribuito di sviluppare e distribuire un'applicazione Web per accedere a un'istanza di Azure SQL Server in modo sicuro. Esistono diversi modi in cui potrei condividere le credenziali per accedere al mio database SQL di Azure:

  • Variabili d'ambiente:questo mantiene i segreti (come le password) fuori dal codice e riduce il rischio che sarebbero vincolati al codice sorgente. Ma le variabili d'ambiente sono archiviate come testo normale, quindi se l'host viene compromesso, quei segreti vanno perduti.
  • Strumento .NET Core Secret Manager:esiste un pacchetto NuGet che consente all'utente di mantenere i segreti dell'applicazione (come una password) in un file JSON archiviato nella directory del profilo utente:ancora una volta, questo riduce il rischio che i segreti possano essere vincolato al codice sorgente, ma dovrei comunque condividere quel segreto per essere archiviato in testo normale.

Nessuna di queste opzioni è l'ideale per me:preferirei concedere l'accesso al mio database SQL di Azure in base al ruolo e non condividere le password con gli sviluppatori che devono essere annotate da qualche parte, in JSON o nei miei script di distribuzione automatizzata. E anche se le due opzioni di cui sopra riducono il rischio che le password siano vincolate al codice sorgente, non eliminano il rischio.

Quindi sono stato davvero entusiasta di leggere di Azure Key Vault (AKV), un modo per archiviare in modo sicuro i segreti nel cloud ed evitare qualsiasi rischio che i segreti vengano salvati nel codice sorgente.

Questa pagina di Microsoft presenta alcune storie utente diverse e come AKV soddisfa queste esigenze, in particolare su:

  • Isolamento dei segreti da applicazioni e sviluppatori
  • Chiavi crittografate:nemmeno Microsoft può vederle
  • Qualsiasi accesso ai segreti in AKV viene registrato
  • I segreti sono archiviati in moduli di sicurezza hardware che sono convalidati FIPS 140-2 livello 2 (link a Wikipedia qui)

(Ci sono ulteriori informazioni su Stack Overflow qui)

Ma dopo aver letto il documento qui sono rimasto un po' sorpreso dal fatto che l'implementazione descritta utilizzasse ancora lo strumento Secret Manager:sembrava che stessimo solo scambiando i segreti di archiviazione in un posto con un altro. Ho cercato in giro per scoprire come farlo senza lo strumento Secret Manager, e in numerosi post e video del blog ho visto gli sviluppatori impostare un segreto in AKV, ma poi copiare un "segreto client" da Azure nel loro codice, e ho pensato questo ha davvero vanificato lo scopo di avere un caveau per i segreti.

Fortunatamente ho trovato quello che devo fare per usare AKV con la mia applicazione Web .NET Core e non devo aggiungere alcun segreto al codice:proteggo la mia applicazione con un'identità del servizio gestito. Ho descritto come eseguire questa operazione di seguito, con il codice C# necessario per utilizzare la funzionalità.

Come mantenere i segreti fuori dal tuo codice sorgente.

  • Prima crea un deposito
  • Aggiungi un segreto al tuo vault
  • Proteggi il tuo servizio app utilizzando Managed Service Identity
  • Accedi al segreto dal tuo codice sorgente con un KeyVaultClient

Tratterò ciascuno di questi a turno, con esempi di codice alla fine per mostrare come accedere all'AKV.

Prima crea un deposito

Apri il portale di Azure ed effettua il login – clicca sulla voce di menu “Tutti i servizi” sul lato sinistro e cerca “key vault” – questo dovrebbe filtrare le opzioni in modo da avere una schermata come quella qui sotto.

Una volta che hai l'opzione Key Vault, fai clic su di essa per vedere una schermata come quella qui sotto che elencherà i Key Vault nel tuo abbonamento. Per creare un nuovo deposito, fai clic sul pulsante "Aggiungi", evidenziato nel documento sottostante.

Questo aprirà un'altra "lama" (che vedo solo come gergo per una finestra mobile) nel portale in cui puoi inserire informazioni sul tuo nuovo deposito.

Come puoi vedere nell'immagine qui sotto, ho chiamato il mio vault "MyWebsiteSecret" e ho creato un nuovo gruppo di risorse chiamato "Development_Secret". Ho scelto la posizione come "Regno Unito occidentale" e per impostazione predefinita il mio utente è stato aggiunto come primo principale che dispone dell'autorizzazione per accedervi.

Ho fatto clic sul pulsante Crea nella parte inferiore dello schermo e il portale presenta un brindisi in alto a destra per dire che il mio deposito è in fase di creazione.

Alla fine questo cambia quando la distribuzione è riuscita.

Pertanto, la schermata del portale di Azure ora mostra di nuovo la pagina dell'elenco e il mio nuovo vault è in questa pagina.

Aggiungi un segreto al deposito

Ora il caveau è stato creato, possiamo creare un nuovo segreto al suo interno. Fai clic sul deposito creato nel passaggio precedente per visualizzare i dettagli di questo deposito (mostrato di seguito).

Ora fai clic sulla voce di menu "Segreti" per aprire una lama che mostra i segreti in questo caveau. Ovviamente, poiché l'ho appena creato, non ci sono ancora segreti. Possiamo creare cliccando sul pulsante "Genera/Importa", evidenziato nell'immagine qui sotto.

Dopo aver cliccato sul pulsante "Genera/Importa", si apre un nuovo pannello in cui puoi inserire i dettagli del tuo segreto. Ho scelto un nome di "TheSecret", ho inserito un valore segreto che è mascherato e ho inserito un po' di testo per il tipo di contenuto per descrivere il tipo di segreto.

Dopo aver fatto clic su "Crea" nella parte inferiore del pannello, il sito mi riporta all'elenco dei segreti in questo deposito, ma questa volta puoi vedere il mio segreto nell'elenco, come mostrato di seguito.

Proteggi il servizio app utilizzando Managed Service Identity

In precedenza ho distribuito la mia applicazione .NET Core in Azure – non entrerò nei dettagli su come distribuire un'applicazione .NET Core poiché è presente in un milione di altri post e video del blog – in pratica ho creato un nuovo servizio app tramite il Portale di Azure e l'ho collegato a un'applicazione .NET Core nel mio profilo GitHub. Ora, quando inserisco il codice in quell'applicazione su GitHub, Azure lo creerà e lo distribuirà automaticamente.

Ma voglio mostrare come creare un'identità del servizio gestito per questa applicazione:come mostrato nell'immagine seguente, ho cercato il mio servizio app in Azure.

Ho selezionato il mio servizio app per aprire un blade con opzioni per questo servizio e ho selezionato "Identità del servizio gestito", come mostrato di seguito. Per impostazione predefinita è disattivato:ho disegnato una freccia sotto accanto al pulsante che ho premuto per attivarlo per il servizio dell'app, quindi ho fatto clic su Salva per mantenere le mie modifiche.

Una volta salvato, dovevo tornare all'insieme di credenziali delle chiavi e al segreto che avevo creato in precedenza e selezionare "Criteri di accesso", come mostrato di seguito. Come accennato in precedenza, il mio nome è lì come autorizzato per impostazione predefinita, ma voglio che anche la mia applicazione abbia l'autorizzazione, quindi ho fatto clic sull'opzione "Aggiungi nuovo", che ho evidenziato con una freccia rossa in basso.

Il pannello sottostante si apre - per principio, ho selezionato il mio servizio app (chiamato "MyAppServiceForTestingVaults") - per impostazione predefinita non viene selezionato nulla, quindi devi solo fare clic sull'opzione per aprire un altro blade in cui puoi cercare il tuo servizio app. Sarà disponibile solo se hai configurato correttamente l'identità del servizio gestito come descritto sopra.

Inoltre, ho selezionato due "Autorizzazioni segrete" dal menu a discesa:Ottieni ed Elenca.

Dopo aver fatto clic su OK, ora posso vedere che la mia applicazione è nell'elenco dei servizi app che hanno accesso al segreto che ho creato in precedenza.

Aggiungi codice alla mia applicazione .NET per accedere a questi segreti

Uso l'estensione per l'autenticazione dei servizi di Azure per semplificare lo sviluppo con il mio account di Visual Studio.

Sceglierò un esempio davvero semplice:modificare l'azione Index di una classe HomeController nel sito Web .NET Core MVC predefinito. Devo anche aggiungere un pacchetto NuGet al mio progetto:

Install-Package Microsoft.Azure.Services.AppAuthentication -Version 1.1.0-preview

Il codice seguente mi consente di autenticarmi nella mia istanza di Azure e ottenere il segreto dal mio vault.

public class HomeController : Controller
{
    public async Task<ActionResult> Index()
    {
        var azureServiceTokenProvider = new AzureServiceTokenProvider();
        var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
        var secret = await keyVaultClient.GetSecretAsync("https://mywebsitesecret.vault.azure.net/secrets/TheSecret").ConfigureAwait(false);
        ViewBag.Secret = secret.Value;
        return View();
    }
    // rest of the class...
}

Ora posso semplicemente modificare la vista Index.cshtml e aggiungere del codice per mostrare il segreto (semplice come aggiungere @ViewBag.Secret nel cshtml) – e quando eseguo il progetto localmente, ora posso vedere che la mia applicazione è stata in grado di accedere al deposito e decrittografare il mio segreto (come evidenziato nell'immagine seguente) senza alcun ID client o informazioni sul segreto client nel mio codice – questo perché la mia macchina riconosce che sono autenticato per accedere alla mia istanza di Azure.

Posso anche distribuire questo codice nel mio Servizio app di Azure e otterrò gli stessi risultati, perché l'identità del servizio gestito dell'applicazione garantisce che la mia applicazione in Azure disponga dell'autorizzazione per accedere al segreto.

Riassumendo

Questo è stato un esempio davvero semplice ed è solo per illustrare come consentire agli sviluppatori di accedere ai segreti AKV senza dover aggiungere informazioni segrete al codice sorgente. Ovviamente, se uno sviluppatore è determinato a compromettere la sicurezza, potrebbe ovviamente decrittografare le password e diffonderle in un altro modo, quindi dovremmo rafforzare la sicurezza per un'applicazione del mondo reale. Ad esempio, potremmo avere segreti diversi archiviati in diversi gruppi di risorse ambientali mentre promuoviamo la nostra applicazione da Dev a QA/Staging e infine a Production.

https://codehollow.com/2017/11/get-started-azure-key-vault/

https://odetocode.com/blogs/scott/archive/2018/03/08/decryption-with-azure-key-vault.aspx

https://docs.microsoft.com/en-us/azure/app-service/app-service-managed-service-identity

https://azure.microsoft.com/en-us/resources/samples/app-service-msi-keyvault-dotnet/


No