이번 포스팅에선 application.yml 에서 주로 입력되는 DB 접속 정보, 각종 키, 파일 경로 등 외부에 공개되면 안되는 민감한 데이터들을 Vault를 이용해서 효율적으로 관리하는 방법을 알아보겠습니다.
HashiCorp Vault 와 Spring Cloud Vault
Vault는 HashiCorp에서 개발한 민감 데이터 관리 솔루션입니다.
Spring Cloud Vault는 Spring Framework 환경에서 Vault를 쉽게 사용할 수 있도록 하는 Spring 확장 라이브러리입니다.
Spring Cloud Config 와 결합하면 Config 서버를 통해 중앙 집중화하여 모든 설정값을 한 곳에서 관리하고 동적 리프레시를 지원합니다.
Demo 서비스
spring boot 프로젝트를 생성하고 간단한 API 를 생성했습니다.
해당 API를 호출하면 애플리케이션의 프로필에 맞게 application.yml의 민감 데이터를 콘솔창에 출력해주는 기능을 구현했습니다.
sampleController
package com.demo.toyproject.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class sampleController {
@Value("${credentials.very-sensitive-data}")
private String verySensitiveData;
@GetMapping("/credentials")
public void printCredentials() {
System.out.println("verySensitiveData = " + verySensitiveData);
}
}
application.yml
credentials:
very-sensitive-data: hello-world
Install Vault
Chocolatey 패키지 매니저를 이용해서 vault 설치
$ choco install vault
Run Vault Server
local에서 실행 가능한 dev server로 vault를 실행합니다.
dev server는 모든 데이터를 메모리에 저장합니다.
$ vault server -dev
서버를 실행하면 VAULT_ADDR 과 Root Token 값을 주는데 이를 환경 변수로 설정합니다.
$ $env:VAULT_ADDR="http://127.0.0.1:8200"
$ $env:VAULT_TOKEN="hvs.mawhL0heT2k6xxKoPCDvDb60"
$ echo $env:VAULT_ADDR
http://127.0.0.1:8200
$ echo $env:VAULT_TOKEN
hvs.mawhL0heT2k6xxKoPCDvDb60
Vault login
http://127.0.0.1:8200에 접속해서 크롬 브라우저를 통해 Vault 서버에 접속하거나 Vault CLI를 통해서 Vault 서버에 접속할 수 있습니다.
$ vault login $env:VAULT_TOKEN
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token hvs.mawhL0heT2k6xxKoPCDvDb60
token_accessor Ym3v5ztCLvDgcTPvZJNj7Uip
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]
Write & Read secret
key-value 형태로 데이터를 저장하기 위해선 특정 경로에 secret engine을 활성화해야합니다.
$ vault secrets enable -path=secret kv
$ vault kv put secret/myapp very-sensitive-data="hello-world"
$ vault kv get secret/myapp
== Secret Path ==
secret/data/myapp
======= Metadata =======
Key Value
--- -----
created_time 2024-11-03T15:47:42.2360653Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
=========== Data ===========
Key Value
--- -----
very-sensitive-data hello-world
$ vault kv get -field=very-sensitive-data secret/myapp
hello-world
Spring Vault 의존성 추가
build.gradle 파일에 spring vault 의존성을 추가해줍니다.
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-vault-config', version: '4.1.3'
application.yml 수정
spring:
config:
import: vault:// # Vault에서 구성 정보를 가져옴
cloud:
vault:
authentication: TOKEN
uri: http://localhost:8200
token: hvs.a19L3ykBBxQK72LCvlGn4C1L
kv:
enabled: true
backend: secret
application-name: myapp
credentials:
very-sensitive-data: ${very-sensitive-data}
테스트
api 실행결과, vault 서버로부터 데이터가 잘 출력되는 것을 확인할 수 있습니다.
정리
이번 포스팅에선 간단히 로컬에서 vault를 실행해보고 key-value 형태로 값을 저장해보는 실습을 진행해보았습니다. 실제 실무에선 위와 같이 적용하기엔 다소 무리가 있고 다음 포스팅에서 좀 더 실무 환경 요구 사항에 적합하게 인프라를 구축해보겠습니다.
참고
https://developer.hashicorp.com/vault/docs
https://sg-choi.tistory.com/624