Spring Cloud Vault

J’ai récemment eu besoin de récupérer des secrets stockés sous Vault dans une application Java Spring Boot. Spring Cloud Vault est le candidat parfait pour ça et je crée un article à la fois en tant que mémento pour moi et en tant que tutoriel pour vous.

Pour ceux qui ne connaissent pas Vault, c’est un coffre-fort développé par HashiCorp, qui permet de stocker des secrets, tokens et certificats pour les rendre accessibles via une UI, un client de ligne de commande ou par API HTTP. Très utile pour stocker vos mots de passe de manière sécurisée et en même temps les partager.

Vault en local

Si vous avez besoin d’expérimenter l’outil, je vous conseille cette commande pour lancer un container docker en local (mot de passe d’accès : root) :

docker run --cap-add=IPC_LOCK -e 'VAULT_DEV_ROOT_TOKEN_ID=root' -p 8200:8200 vault

Vous aurez donc accès à l’interface à l’adresse http://localhost:8200 ou via API avec :

curl -H "X-Vault-Token: root" -X GET http://127.0.0.1:8200/v1/secret/foo

Ajoutez un secret sous secret/vaultdemo/dev avec deux clés username et password :

Spring Cloud Vault

Passons maintenant à la partie applicative, notre projet Spring Boot. L’idée est de récupérer au démarrage les secrets de notre application (par environnement). Nous utilisons Spring Cloud Vault et pas Spring Vault. Je trouve que la partie Cloud permet une installation/configuration vraiment simple. Si vous avez besoin de plus de légèreté ou d’une configuration plus fine, ça vaut peut-être le coup de tester aussi Spring Vault.

Pour contacter Vault, votre application aura besoin de s’authentifier et plusieurs méthodes sont possibles. La plus simple est l’utilisation d’un token, exemple que nous allons configurer ici. Mais il existe de nombreuses méthodes, surtout avec les providers de Cloud (AWS, GCP, Azure, …) : https://cloud.spring.io/spring-cloud-vault/reference/html/#vault.config.authentication

Nous ajoutons donc les dépendances nécessaires (Gradle) :

'org.springframework.cloud:spring-cloud-vault-config:2.2.5.RELEASE',
// Nécessaire si vous utilisez l'authentification AWS
//'com.amazonaws:aws-java-sdk:1.11.887',
//'com.amazonaws:aws-java-sdk-sts:1.11.887',

Il faut ensuite configurer l’accès à Vault dans un fichier bootstrap.yml :

spring.cloud.vault:
    fail-fast: true // Stop l'application si la connexion à Vault échoue
    uri: http://localhost:8200 // URL de Vault avec protocole
    connection-timeout: 5000
    read-timeout: 15000
    authentication: TOKEN
    token: root
    generic:
        enabled: false
    kv:
        enabled: true
    config:
        order: -10

Spring Cloud Vault va aller chercher directement dans l’arborescence de Vault en testant ces paths :

/secret/{application}/{profile}
/secret/{application}

application étant le nom configuré avec spring.application.name (dans notre cas vaultdemo) et profile étant le profil Spring actif


Une fois ce paramétrage effectué, Spring va contacter Vault au démarrage et exposer les secrets dans l’environnement Spring. Il est donc possible d’y accéder depuis un fichier de configuration application.yml :

account_username=${username}
account_password=${password}

ou à n’importe quel moment dans le code

@Autowired Environment env;
public String getUsername() {
    return env.getProperty("username");
}

Démarrez votre application en veillant à activer le profile dev (-Dspring.profiles.active=dev)

Les parties les plus complexes ont été pour moi la configuration de l’authentification (autre que par Token) et la configuration du path (quand votre Vault n’est pas configuré comme Spring Cloud Vault le prévoit…).

Stocker les secrets dans Vault permet de vraiment séparer les rôles et c’est un outil assez simple à mettre en place et assez répandu aujourd’hui pour que les frameworks comme Spring permettent son intégration facilement.

Si vous avez des remarques, compléments ou questions, n’hésitez pas à laisser un commentaire.

Vous aimerez aussi...

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *