이번 포스팅에선 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

스크린샷 2024-11-04 003157

서버를 실행하면 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"]

스크린샷 2024-11-04 005604

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 서버로부터 데이터가 잘 출력되는 것을 확인할 수 있습니다.

스크린샷 2024-11-04 021747

정리

이번 포스팅에선 간단히 로컬에서 vault를 실행해보고 key-value 형태로 값을 저장해보는 실습을 진행해보았습니다. 실제 실무에선 위와 같이 적용하기엔 다소 무리가 있고 다음 포스팅에서 좀 더 실무 환경 요구 사항에 적합하게 인프라를 구축해보겠습니다.

참고

https://developer.hashicorp.com/vault/docs
https://sg-choi.tistory.com/624