🔒 보안

HashiCorp Vault

HashiCorp Vault

시크릿 관리 도구. 동적 시크릿, 암호화, 접근 제어.

📖 상세 설명

HashiCorp Vault는 시크릿(비밀번호, API 키, 인증서 등)을 안전하게 저장, 접근, 관리하는 도구입니다. 단순한 저장소가 아니라, 동적 시크릿 생성, 암호화 서비스, 세밀한 접근 제어, 감사 로깅을 제공하는 완전한 시크릿 관리 플랫폼입니다.

Vault의 핵심 기능 중 하나는 동적 시크릿(Dynamic Secrets)입니다. 데이터베이스 접근이 필요할 때마다 임시 자격 증명을 생성하고, TTL(Time To Live) 후 자동 폐기합니다. 시크릿이 유출되어도 수명이 짧아 피해가 제한됩니다. AWS, GCP, Azure, PostgreSQL, MySQL 등 다양한 백엔드를 지원합니다.

Transit 시크릿 엔진은 데이터 암호화 서비스를 제공합니다. 애플리케이션이 암호화 키를 직접 관리하지 않고, Vault API를 통해 암/복호화를 수행합니다. 키 로테이션, 다양한 암호화 알고리즘 지원, HSM(Hardware Security Module) 통합이 가능합니다.

Vault는 다양한 인증 방식(LDAP, OIDC, Kubernetes, AWS IAM 등)과 세밀한 정책 기반 접근 제어를 제공합니다. 모든 작업은 감사 로그에 기록되어 컴플라이언스 요구사항을 충족합니다. Kubernetes 환경에서는 Vault Agent Injector로 Pod에 시크릿을 자동 주입할 수 있습니다.

💻 코드 예제

# Vault CLI 기본 사용

# 1. KV (Key-Value) 시크릿 저장/조회
vault kv put secret/myapp/config \
  db_host="db.example.com" \
  db_user="app_user" \
  db_password="super-secret-123"

vault kv get secret/myapp/config
vault kv get -field=db_password secret/myapp/config

# 2. 동적 데이터베이스 시크릿 설정
# PostgreSQL 시크릿 엔진 활성화
vault secrets enable database

# 데이터베이스 연결 설정
vault write database/config/mydb \
  plugin_name=postgresql-database-plugin \
  connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/mydb" \
  allowed_roles="app-role" \
  username="vault_admin" \
  password="admin-password"

# 역할 생성 (임시 자격 증명 템플릿)
vault write database/roles/app-role \
  db_name=mydb \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
    GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
  default_ttl="1h" \
  max_ttl="24h"

# 동적 자격 증명 생성 (1시간 후 자동 폐기)
vault read database/creds/app-role
# username: v-token-app-role-xxx
# password: A1b2C3d4E5F6...
# lease_duration: 1h

# --------------------------------------------------------
# Node.js에서 Vault 사용
import Vault from 'node-vault';

const vault = Vault({
  apiVersion: 'v1',
  endpoint: 'https://vault.example.com:8200',
  token: process.env.VAULT_TOKEN
});

// KV 시크릿 조회
async function getSecrets() {
  const result = await vault.read('secret/data/myapp/config');
  return result.data.data; // { db_host, db_user, db_password }
}

// 동적 DB 자격 증명 획득
async function getDatabaseCredentials() {
  const result = await vault.read('database/creds/app-role');
  return {
    username: result.data.username,
    password: result.data.password,
    leaseId: result.lease_id,
    leaseDuration: result.lease_duration
  };
}

// Transit 엔진으로 데이터 암호화
async function encryptData(plaintext: string) {
  const result = await vault.write('transit/encrypt/my-key', {
    plaintext: Buffer.from(plaintext).toString('base64')
  });
  return result.data.ciphertext; // vault:v1:xxxxx
}

async function decryptData(ciphertext: string) {
  const result = await vault.write('transit/decrypt/my-key', {
    ciphertext: ciphertext
  });
  return Buffer.from(result.data.plaintext, 'base64').toString();
}

🗣️ 실무 대화 예시

DevSecOps 전환에서:

".env 파일에 시크릿 하드코딩하는 거 보안 감사에서 지적받았어요. Vault 도입하면 시크릿 중앙 관리, 접근 로깅, 동적 자격 증명까지 가능합니다. Kubernetes라면 External Secrets Operator로 연동하면 돼요."

기술 면접에서:

"동적 시크릿의 장점은?" - "정적 비밀번호는 유출 시 영구적 위험이 있지만, 동적 시크릿은 짧은 TTL로 생성되어 자동 폐기됩니다. 공격자가 탈취해도 이미 만료되어 있을 가능성이 높아요."

아키텍처 설계에서:

"Vault HA 구성은 어떻게 하나요?" - "최소 3노드 클러스터로 Raft 스토리지 사용해요. 리더-팔로워 구조로 리더 장애 시 자동 선출됩니다. 프로덕션에선 Auto Unseal(AWS KMS 등)도 필수입니다."

⚠️ 주의사항

🔗 관련 용어

External Secrets Sealed Secrets SOPS Secret 암호화

📚 더 배우기

📄 HashiCorp Vault 공식 문서 📄 Vault 튜토리얼 📄 HashiCorp Learn - Vault