Introduzione

Fin dalle prime volte che abbiamo iniziato a mettere insieme qualche riga di codice per creare un applicativo, abbiamo sentito la necessità di mettere al sicuro alcune informazioni legate a ciò che stavamo facendo.

Nell'arco della nostra vita professionale abbiamo usato tanti metodi, ma nell'era del cloud non si può far a meno di volgere lo sguardo verso qualcosa che non sia relegato al nostro client o a un server aziendale. A tal proposito, Microsoft offre una serie di soluzioni che permettono di salvaguardare gli aspetti che devono rimanere segreti nella nostra applicazione, per archiviarli ed accedervi in modo sicuro.

Lo strumento consigliato è Azure Key Vault

Perché Azure Key Vault 

Azure Key Vault (AKV) offre le seguenti funzionalità:

Gestione dei secret: archiviazione sicura e controllo rigoroso dell'accesso a token, password, certificati, chiavi API.

Gestione delle chiavi: creazione e controllo delle chiavi di crittografia usate per crittografare i dati.

Gestione dei certificati: provisioning, gestione e distribuzione dei certificati Transport Layer Security/Secure Sockets Layer (TLS/SSL) pubblici e privati da usare con Azure e le risorse connesse interne.

Archiviazione dei secret supportati da moduli di protezione hardware: le chiavi possono essere protette da software o da moduli di protezione hardware certificati FIPS 140-2 livello 2.

L’elemento cardine in AKV è il “secret”, di cui si vuole controllare in maniera sicura l’accesso una volta archiviato su Azure. Esempi di secret possono essere: chiavi API, stringhe di connessione ai database, certificati, password di accesso etc.

I secret in AKV sono gestiti dall'owner che può non solo crearli, ma anche gestirne la configurazione delle autorizzazioni per regolare gli accessi da parte dei client consumer e per coordinare l’audit. Può anche controllare il ciclo di vita delle chiavi, passando ad una nuova versione della chiave o eseguendo il backup.

Per comprendere alcuni concetti alla base dell’uso di AKV, bisogna avere chiaro cosa sono i Service Principal e le Managed Identity. Si tratta di concetti strettamente legati alla sicurezza che Azure offre e all’uso delle app che vengono appunto “hostate” su Azure.

Nello specifico, il Service Principal è un'identità di sicurezza usata da app, servizi e strumenti di automazione creati dall'utente per accedere a risorse specifiche di Azure. È una sorta di "identità utente" (nome utente e password o certificato) con un ruolo e autorizzazioni specifiche. A differenza di un'identità utente generica, un Service Principal potrà eseguire solo determinate operazioni.

Le Managed Entity, una funzionalità di Azure Active Directory supportata da tutti i servizi di Azure, rappresentano il modo che, da sviluppatori e non, abbiamo per accedere alle chiavi ed ai secret di AKV, in quanto anche per ottenere le informazioni contenute nei secret dobbiamo essere autenticati.

Le Managed Entity consentono di accedere ai secret aziendali assegnando ai servizi di Azure un'identità gestita automaticamente in Azure AD. È possibile usare questa identità per l'autenticazione in AKV o in qualsiasi servizio che supporti l'autenticazione di Azure AD, senza dover inserire le credenziali nel codice.

Di seguito, il flusso a cui il nostro codice è sottoposto per poter accedere ad AKV.

Azure AD Tenant

I secret archiviati su AKV sono raggiungibili via API quando necessario, ricordiamo che queste chiavi vengono protette da Azure con algoritmi standard del settore, lunghezza delle chiavi e moduli di protezione hardware.

Azure-Key-Vault

Come procedere alle configurazioni per utilizzare Azure Key Vault 

Dopo questa panoramica riguardo le tecnologie sottostanti AKV, possiamo passare ad un esempio pratico illustrando come integrare una risorsa dell’insieme di credenziali di AKV con un'app Web ASP.NET Core in esecuzione nel servizio app di Azure.

Per iniziare, creeremo una risorsa di tipo AKV sul nostro portale Azure all’interno di un Resource group (Studio nell’immagine):

Key-Vault

A questo punto inseriamo tutti i dati necessari nella schermata successiva (per maggiori dettagli rimandiamo alla documentazione ufficiale in cui si troveranno le differenze di pricing tra il livello di servizio standard e premium e anche informazioni sul nome da dare alla chiave, importante perché farà parte dell’hostname del DNS pubblico). 

Create-Key-Vault

Nella schermata successiva è possibile verificare quanto prima abbiamo appreso sulle access policy legate all’identity management gestite di default da Azure in fase di creazione di un Key Vault. Notiamo, infatti, le Key Permissions, i Secret Permissions ed i Certificate Permissions per l’utente corrente impostate da Azure, che è possibile modificare per limitare o permettere azioni all'utente corrente.

Si può, anche in questa fase di creazione, aggiungere un altro utente e relative policy al Key Vault corrente partendo da un template (come indicato dalla freccia rossa). Ma vedremo successivamente come sfruttare questa funzionalità. 

Access-policy

La pagina successiva permette di scegliere la modalità di deploy del Vault per permetterne la fruizione lato client. 

Networking 

Terminiamo la procedura creando il Key Vault, dal quale sarà possibile ottenere l’endpoint da utilizzare nel nostro codice per accedere alle chiavi o secret, nel nostro caso: https://vault-aspnetcore-web.vault.azure.net/ (è possibile eseguire la procedura anche con Azure CLI). 

A questo punto siamo pronti per inserire i nostri secret da archiviare su Azure Key Vault per la nostra applicazione e lo faremo sempre manualmente dal portale di Azure. 

Vault-Aspnetcore-Web 

Selezionando Secrets e successivamente la voce di menu Import/Create Secret sarà possibile salvare su AKV. 

Create-a-Secret

Attraverso la selezione del Key Vault appena creato si può notare che se ne può creare una nuova versione ed anche scaricarne un backup.

My-Super-Secret-Password 

Ora possiamo creare il nostro client per dimostrare l’utilizzo via codice del Vault creato.

Come creare un’app Web da hostare su Azure esula dal contesto di questo articolo, ma sulla documentazione ufficiale Microsoft si può trovare qualunque approfondimento. Per i nostri scopi utilizzeremo un’applicazione ASP-NET Core di tipo Razor Pages.

Possiamo però prima fare un test direttamente dalla Cloud Shell come nelle seguenti schermate dove utilizzeremo Bash come command shell (l’alternativa è Powershell ma ad oggi presenta dei malfunzionamenti). 

Vault-Aspnetcore-web-secrets

Per scoprire i comandi a disposizione possiamo scrivere:

az keyvault -h 

questa regola vale anche per i sottocomandi, ad esempio se volessimo conoscere i comandi per avere informazioni e gestire i secret:

az keyvault secret show -h e quindi per avere informazioni sui secret del nostro AKV: 

Coding-command

Utilizzeremo il comando seguente che evidenzia l’id del secret come parametro: 

az keyvault secret show --id https://vault-aspnetcore-web.vault.azure.net/secrets/MySuperSecretPassword/fe2aa757ed1248dd9bebf9acbee2bce2

Az-Keyvault- secret-show

Dove la parte finale rappresenta la versione corrente del secret.

Dal risultato vediamo che riusciamo ad ottenere i dati che ci occorrono sotto forma di JSON, la proprietà Value contiene il secret che abbiamo precedentemente inserito nel Vault. 

Non ci resta che pubblicare la nostra app su Azure utilizzando un App Service appositamente creato e poi modificare la nostra pagina di startup per recuperare il secret da AKV.

Prima di questo passaggio, dobbiamo capire come far dialogare l’insieme di credenziali in cui sono custoditi i nostri secret e la nostra app. Il modo più semplice è configurarlo sul portale di Azure.

Accedendo al nostro App Service possiamo selezionare dal menu di sinistra la voce Identity che ci permetterà di definire l’altro pilastro di cui abbiamo parlato prima: le Managed Entity per la nostra applicazione. Qui notiamo che abbiamo una doppia scelta, o affidarci a una identity gestita dal sistema oppure a una gestita dall’utente.

Già da questa schermata si intuisce che il collegamento che cerchiamo è qui, Azure ti aiuta nominando AKV come uno dei possibili servizi che possono usufruire delle service identity.

Abilitando la voce Status viene assegnata dal sistema un’identità gestita, che consente alle risorse di Azure di autenticarsi nei servizi cloud (come ad esempio Azure Key Vault) senza archiviare le credenziali nel codice. Tutte le autorizzazioni necessarie, infatti, possono essere concesse tramite il controllo degli accessi in base al ruolo di Azure (RBAC). 

 Demo-Key-Vault

 

System-Assigned

Una volta effettuata l’operazione, è possibile verificare, tornando al nostro AKV, che si può aggiungere un altro criterio di accesso a cui dare l’autorizzazione per accedere al nostro AKV utilizzando i secret.

Selezionando il template Secret Management troviamo abilitate di default tutte le permissions standard per le possibili operazioni su AKV, per i nostri scopi useremo solo quelle di lettura (Get e List).

Proseguendo nella configurazione, selezioniamo, come Service Principal, l’app service che abbiamo creato in precedenza, nel nostro esempio DemoKeyVault20200223060426 

Add-access-policy

Questa è la nostra identità gestita, l'account di servizio generato per l'applicazione web quando abbiamo creato l'identità del Managed Service.

Enable-access

Questo è l’ultimo passaggio da realizzare per configurare ciò che serve per lavorare con AKV lato infrastruttura. 

Tutto quello che adesso dobbiamo fare è utilizzare questo meccanismo nella nostra app e dimostrare che, appena si “presenta” al nostro gestore di credenziali (Azure AD nel nostro caso) quest’ultimo lo “riconosce” come “utente” regolarmente da autenticare in base alla configurazione fatta in precedenza.

Nell’esempio, di cui troverete i dettagli tra le risorse collegate all’articolo, abbiamo aggiunto il codice seguente in fase di startup dell’applicazione.     

 

         public async Task OnGetAsync()

        {

 

            try

            {

 

AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();

 KeyVaultClient keyVaultClient = new KeyVaultClient(new          KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

var secret = await keyVaultClient.GetSecretAsync(GetKeyVaultSecretsEndpoint())

                        .ConfigureAwait(false);

                Message = secret.Value;

            }

           

            /// <exception cref="KeyVaultErrorException">

            /// Sollevo un eccezione se l'operazione ritorni uno status code non valido

            /// </exception>

            catch (KeyVaultErrorException keyVaultException)

            {

                Message = keyVaultException.Message;

            }

        }

Il risultato.

 

Azure-Key-Vault

I campi di applicazione di questo meccanismo sono molteplici, l'elemento importante è far capire, non solo agli sviluppatori, visto che quanto detto vale per qualunque scenario, che gli strumenti a disposizione esistono e non sono complessi da utilizzare e da implementare.

 

 

comments powered by Disqus