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.
Derniers commentaires