Un'introduzione a Spring Cloud Vault

1. Panoramica

In questo tutorial, mostreremo come possiamo utilizzare Hashicorp's Vault nelle applicazioni Spring Boot per proteggere i dati di configurazione sensibili.

Presumiamo qui una certa conoscenza di Vault e che abbiamo una configurazione di prova già attiva e funzionante . Se questo non è il caso, prendiamoci un momento per leggere il nostro tutorial Vault Intro in modo da poter familiarizzare con le sue basi.

2. Spring Cloud Vault

Spring Cloud Vault è un'aggiunta relativamente recente allo stack Spring Cloud che consente alle applicazioni di accedere ai segreti archiviati in un'istanza di Vault in modo trasparente .

In generale, la migrazione a Vault è un processo molto semplice: basta aggiungere le librerie richieste e aggiungere alcune proprietà di configurazione extra al nostro progetto e dovremmo essere a posto. Non sono necessarie modifiche al codice!

Questo è possibile perché agisce come una priorità PropertySource registrato nella corrente ambiente .

In quanto tale, Spring lo utilizzerà ogni volta che è richiesta una proprietà. Gli esempi includono proprietà DataSource , ConfigurationProperties e così via.

3. Aggiunta di Spring Cloud Vault a un progetto Spring Boot

Per includere la libreria spring-cloud-vault in un progetto Spring Boot basato su Maven, utilizziamo l' artefatto di avvio associato , che estrarrà tutte le dipendenze richieste.

Oltre allo starter principale , includeremo anche i database spring-vault-config , che aggiunge il supporto per le credenziali del database dinamico:

 org.springframework.cloud spring-cloud-starter-vault-config   org.springframework.cloud spring-cloud-vault-config-databases 

L'ultima versione dello starter Spring Cloud Vault può essere scaricata da Maven Central.

3.1. Configurazione di base

Per funzionare correttamente, Spring Cloud Vault ha bisogno di un modo per determinare dove contattare il server Vault e come autenticarsi su di esso.

Lo facciamo fornendo le informazioni necessarie in bootstrap.yml o bootstrap.properties :

# bootstrap.yml spring: cloud: vault: uri: //localhost:8200 ssl: trust-store: classpath:/vault.jks trust-store-password: changeit 

La proprietà spring.cloud.vault.uri punta all'indirizzo API di Vault. Poiché il nostro ambiente di test utilizza HTTPS con un certificato autofirmato, dobbiamo anche fornire un keystore contenente la sua chiave pubblica.

Notare che questa configurazione non ha dati di autenticazione . Per il caso più semplice, dove usiamo un token fisso, possiamo passarlo attraverso la proprietà di sistema spring.cloud.vault.token o una variabile d'ambiente. Questo approccio funziona bene in combinazione con meccanismi di configurazione cloud standard, come ConfigMaps di Kubernetes o Docker secrets.

Spring Vault richiede anche una configurazione aggiuntiva per ogni tipo di segreto che vogliamo utilizzare nella nostra applicazione. Le sezioni seguenti descrivono come aggiungere il supporto a due tipi di segreti comuni: chiave / valore e credenziali del database.

4. Utilizzo del backend Generic Secrets

Usiamo il backend segreto generico di accesso senza versione segreti memorizzati come coppie chiave-valore in Vault .

Supponendo di avere già la dipendenza spring-cloud-starter-vault-config nel nostro classpath , tutto ciò che dobbiamo fare è aggiungere alcune proprietà al file di configurazione bootstrap.yml dell'applicazione:

spring: cloud: vault: # other vault properties omitted ... generic: enabled: true application-name: fakebank 

La proprietà nome-applicazione in questo caso è facoltativa. Se non specificato, Spring assumerà invece il valore dello standard spring.application.name .

Ora possiamo utilizzare tutte le coppie chiave / valore memorizzate in secret / fakebank come qualsiasi altra proprietà dell'ambiente . Il frammento di codice seguente mostra come leggere il valore della chiave foo memorizzata in questo percorso:

@Autowired Environment env; public String getFoo() { return env.getProperty("foo"); } 

Come possiamo vedere, il codice stesso non sa nulla di Vault, il che è positivo! Possiamo ancora utilizzare proprietà fisse nei test locali e passare a Vault a nostro piacimento abilitando solo una singola proprietà in bootstrap.yml .

4.1. Una nota sui profili di primavera

Se disponibile nell'ambiente corrente , Spring Cloud Vault utilizzerà i nomi dei profili disponibili come suffisso aggiunto al percorso di base specificato in cui verranno cercate le coppie chiave / valore .

Cercherà anche le proprietà in un percorso dell'applicazione predefinito configurabile (con e senza un suffisso del profilo) in modo da poter condividere i segreti in un'unica posizione. Usa questa funzione con cautela!

Per riassumere, se il profilo di produzione della nostra applicazione fakebank è attivo, Spring Vault cercherà le proprietà archiviate nei seguenti percorsi:

  1. secret / fakebank / production (priorità più alta)
  2. secret / fakebank
  3. segreto / applicazione / produzione
  4. segreto / applicazione (priorità inferiore)

Nell'elenco precedente, application è il nome che Spring utilizza come posizione aggiuntiva predefinita per i segreti. Possiamo modificarlo usando la proprietà spring.cloud.vault.generic.default-context .

Le proprietà memorizzate nel percorso più specifico avranno la precedenza sulle altre. Ad esempio, se la stessa proprietà pippo è disponibile nei percorsi sopra, l'ordine di precedenza sarebbe:

5. Utilizzo del back-end segreto del database

Il modulo Database backend consente alle applicazioni Spring di utilizzare credenziali di database generate dinamicamente create da Vault . Spring Vault inserisce tali credenziali nelle proprietà standard spring.datasource.username e spring.datasource.password in modo che possano essere selezionate dai normali DataSource .

Tieni presente che, prima di utilizzare questo backend, dobbiamo creare una configurazione del database e ruoli in Vault come descritto nel nostro tutorial precedente.

Per poter utilizzare le credenziali del database generate da Vault nella nostra applicazione Spring, i database spring-cloud-vault-config devono essere presenti nel classpath del progetto, insieme al driver JDBC corrispondente.

Abbiamo anche bisogno di abilitarne l'uso nella nostra applicazione aggiungendo alcune proprietà al nostro bootstrap.yml:

spring: cloud: vault: # ... other properties omitted database: enabled: true role: fakebank-accounts-rw

La proprietà più importante qui è la proprietà del ruolo , che contiene un nome di ruolo del database archiviato in Vault. Durante il bootstrap, Spring contatterà Vault e chiederà di creare nuove credenziali con i privilegi corrispondenti.

Per impostazione predefinita, il vault revocherà i privilegi associati a tali credenziali dopo il time-to-live configurato.

Fortunatamente, Spring Vault rinnoverà automaticamente il contratto di locazione associato alle credenziali acquisite. In questo modo, le credenziali rimarranno valide finché la nostra applicazione è in esecuzione.

Ora, vediamo questa integrazione in azione. Il frammento di codice seguente ottiene una nuova connessione al database da un DataSource gestito da Spring :

Connection c = datasource.getConnection(); 

Ancora una volta, possiamo vedere che non vi è alcun segno di utilizzo di Vault nel nostro codice . Tutta l'integrazione avviene a livello di ambiente , quindi il nostro codice può essere facilmente testato come al solito.

6. Conclusione

In questo tutorial, abbiamo mostrato come integrare Vault con Spring Boot utilizzando la libreria Spring Vault. Abbiamo coperto due casi d'uso comuni: coppie chiave / valore generiche e credenziali di database dinamiche.

Un progetto di esempio contenente tutte le dipendenze richieste, i test di integrazione e gli script di configurazione del vault è disponibile su GitHub.