/엔지니어/보안 설정/HashiCorp Vault 기초 — 시크릿 관리와
보안 설정고급linuxvaultsecretshashicorp

HashiCorp Vault 기초 — 시크릿 관리와 동적 자격증명

HashiCorp Vault의 핵심 개념(seal/unseal, 토큰, 정책, 시크릿 엔진)을 정리하고 KV v2 정적 시크릿과 데이터베이스 동적 자격증명, AppRole 인증까지 실습합니다.

HashiCorp Vault 란?

Vault는 API 키, DB 비밀번호, 인증서 같은 시크릿(secret)을 중앙에서 안전하게 보관·발급·감사하는 도구입니다. 코드에 비밀번호를 하드코딩하거나 환경변수 파일을 여기저기 뿌리는 방식의 근본적 위험을 해결합니다.

Vault의 강력한 차별점은 **동적 시크릿(dynamic secrets)**입니다. 정적 비밀번호를 저장만 하는 게 아니라, 애플리케이션이 요청할 때마다 짧은 수명의 DB 계정을 즉석에서 생성하고 TTL이 지나면 자동 폐기합니다. 비밀번호가 유출되어도 수명이 짧아 피해가 제한되고, 자격증명이 누구에게 언제 발급됐는지 모두 감사 로그에 남습니다.

이 가이드는 단일 노드 개발/스테이징 환경 기준으로 Vault의 핵심 개념과 주요 워크플로(KV 시크릿, DB 동적 자격증명, AppRole)를 다룹니다.

이 문서의 vault server -dev는 학습용입니다. 메모리에만 데이터를 두고 자동 unseal되며 TLS도 없습니다. 운영에는 절대 사용하지 마세요. 운영은 영속 스토리지(Integrated Storage/Raft) + TLS + 분산 unseal 키 구성이 필요합니다.

핵심 개념

개념설명
Seal / UnsealVault는 시작 시 암호화된 봉인 상태. 마스터 키 조각으로 unseal해야 데이터 접근 가능
Unseal Key (Shamir)마스터 키를 N개 조각으로 분할, K개 모여야 복호화(예: 5개 중 3개)
Root Token모든 권한을 가진 초기 토큰. 작업 후 폐기 권장
Token모든 요청은 토큰으로 인증. TTL과 정책이 부여됨
PolicyHCL로 작성하는 경로별 권한(capabilities)
Secrets Engine시크릿을 다루는 플러그인(kv, database, pki 등)
Auth Method사용자/앱 인증 방식(token, approle, userpass, kubernetes)

서버 기동과 unseal

학습용 dev 서버:

Bash
vault server -dev -dev-root-token-id="root"
# 출력된 VAULT_ADDR, Root Token을 메모

운영형 기동(Raft 스토리지)은 config 파일을 사용합니다.

HCL
# /etc/vault.d/vault.hcl
storage "raft" {
  path    = "/opt/vault/data"
  node_id = "node1"
}
listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_cert_file = "/etc/vault.d/tls/vault.crt"
  tls_key_file  = "/etc/vault.d/tls/vault.key"
}
api_addr = "https://vault.example.com:8200"
ui = true
Bash
export VAULT_ADDR='https://vault.example.com:8200'
vault operator init          # unseal 키 5개 + root 토큰 발급 (안전 보관!)
vault operator unseal        # 키 3개를 각각 입력
vault status                 # Sealed: false 확인

vault operator init 출력(unseal 키, root 토큰)은 단 한 번만 표시됩니다. 분실하면 데이터를 영구히 잃습니다. 키 조각은 서로 다른 담당자/금고에 분산 보관하세요.

CLI 로그인

Bash
export VAULT_ADDR='http://127.0.0.1:8200'
vault login                  # 토큰 입력 (dev면 root)
vault token lookup           # 현재 토큰 정보·TTL·정책 확인

KV v2 — 정적 시크릿

가장 기본적인 시크릿 저장소입니다. v2는 버전 관리와 소프트 삭제를 지원합니다.

Bash
# KV v2 엔진 활성화
vault secrets enable -path=secret kv-v2

# 시크릿 저장
vault kv put secret/myapp/db username="appuser" password="s3cr3t"

# 조회
vault kv get secret/myapp/db
vault kv get -field=password secret/myapp/db    # 값만 추출

# 버전 관리
vault kv get -version=1 secret/myapp/db
vault kv metadata get secret/myapp/db           # 버전 이력

# 소프트 삭제 / 복구 / 완전 삭제
vault kv delete secret/myapp/db
vault kv undelete -versions=2 secret/myapp/db
vault kv destroy -versions=1 secret/myapp/db

KV v2는 API 경로에 /data/가 끼어든다는 점에 유의해야 합니다(정책 작성 시 중요).

정책(Policy)

권한은 경로별 capabilities로 정의합니다.

HCL
# myapp-policy.hcl
# KV v2이므로 실제 경로는 secret/data/...
path "secret/data/myapp/*" {
  capabilities = ["read", "list"]
}
path "secret/metadata/myapp/*" {
  capabilities = ["list", "read"]
}
Bash
vault policy write myapp myapp-policy.hcl
vault policy read myapp

capabilities는 create, read, update, delete, list, sudo, deny가 있으며 최소 권한 원칙으로 부여합니다.

동적 자격증명 — Database 시크릿 엔진

Vault가 PostgreSQL에 접속해 요청 시마다 임시 계정을 만들어주는 구성입니다.

Bash
# 엔진 활성화
vault secrets enable database

# DB 연결 설정 (Vault가 사용할 관리자 계정)
vault write database/config/postgres \
    plugin_name=postgresql-database-plugin \
    allowed_roles="readonly" \
    connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/app?sslmode=require" \
    username="vault_admin" \
    password="adminpass"

# 역할 정의: 발급 시 실행할 SQL과 TTL
vault write database/roles/readonly \
    db_name=postgres \
    creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
    default_ttl="1h" \
    max_ttl="24h"

이제 자격증명을 요청하면:

Bash
vault read database/creds/readonly
# Key                Value
# lease_id           database/creds/readonly/abc123
# lease_duration     1h
# username           v-token-readonly-x9f2...
# password           A1b2-randomgenerated

발급된 계정은 1시간 뒤 자동 폐기됩니다. 즉시 회수하려면:

Bash
vault lease revoke database/creds/readonly/abc123

동적 자격증명을 쓰려면 Vault 관리자 계정이 DB에서 CREATEROLE 권한을 가져야 합니다. 이 관리자 계정 자체도 vault write database/rotate-root/postgres로 주기 교체하세요.

AppRole — 애플리케이션 인증

사람이 아닌 애플리케이션/CI가 Vault에 인증하는 표준 방식입니다.

Bash
vault auth enable approle

vault write auth/approle/role/myapp \
    token_policies="myapp" \
    token_ttl=1h token_max_ttl=4h \
    secret_id_ttl=24h

# RoleID(공개) + SecretID(비밀) 발급
vault read auth/approle/role/myapp/role-id
vault write -f auth/approle/role/myapp/secret-id

# 두 값으로 로그인 → 단기 토큰 획득
vault write auth/approle/login \
    role_id="<role_id>" secret_id="<secret_id>"

RoleID는 빌드에 박아두고 SecretID는 런타임에 안전하게 주입하는 패턴(예: CI 시크릿)을 씁니다.

감사 로그

Bash
vault audit enable file file_path=/var/log/vault/audit.log

모든 요청·응답이 해시된 형태로 기록됩니다. 컴플라이언스 대응의 핵심입니다.

정리

항목핵심
Seal/Unseal시작 시 봉인, Shamir 키 K-of-N으로 해제
KV v2정적 시크릿, 버전·소프트삭제, 경로에 /data/
Policy경로별 capabilities, 최소 권한
Database 엔진요청 시 임시 계정 생성, TTL 후 자동 폐기
AppRoleRoleID + SecretID로 앱 인증
감사vault audit enable로 전체 요청 기록

Vault의 진가는 정적 시크릿 보관을 넘어 동적·단기 자격증명에 있습니다. "비밀번호를 저장하지 말고 필요할 때 짧게 발급하라"가 핵심 사고방식입니다.

#vault#secrets#hashicorp#security#kv
편집 안내 · Editorial Note

이 가이드는 AI 도구를 활용해 초안을 구성하고 사람이 명령어·문맥을 검토해 발행했습니다. 운영체제와 도구 버전에 따라 결과가 달라질 수 있으므로 적용 전 공식 문서를 함께 확인하세요. 오류를 발견하시면 이메일로 제보해 주세요.

질문 & 답변 (Q&A)

이 가이드에 대해 궁금한 점을 질문해보세요. 확인 후 답변드립니다.