Boundary의 데이터 암호화

Boundary의 데이터 암호화

Boundary는 목적별로 만들어진 KMS 키를 사용해 저장 데이터(자격 증명, 워커 인증 자료, 세션 토큰)를 암호화해요. 각 기능을 격리해서 단일 키가 침해돼도 관련 없는 데이터를 복호화할 수 없도록 하는 거죠. 이 페이지에서는 Boundary가 지원하는 각 KMS 키의 목적과 키 버전을 회전하거나 파기하는 방법을 다뤄요.

출처: HashiCorp Boundary docs

본문

worker-auth-storage KMS 키

worker-auth-storage KMS 키는 worker-led 또는 controller-led 방식으로 등록된 워커가 인증 키를 저장하는 데 사용할 수 있어요. 워커에게는 선택 사항이며, 지정하지 않으면 인증 키가 디스크에 암호화되지 않은 채 남아요. 외부 KMS로 등록된 워커는 이 키를 사용할 수 없어요.

root KMS 키와 스코프별 KEK/DEK

용도가 다른 키를 서로 다르게 쓰는 모범 사례에 따라 Boundary는 각 스코프 안에서 여러 암호화 키를 생성해요. 각 키는 다시 버전을 가지며, 버전이 데이터를 암호화하는 데 사용된 키 자료를 보유해요. 키를 회전하면 새 키 버전을 만들 수 있어요. 키 버전을 파기하면 기존 데이터를 다시 암호화한 다음 키 자료를 영구 폐기해요.

root KMS 키는 스코프별 KEK(Key Encrypting Key, 키 암호화 키, 스코프의 root 키라고도 불러요)의 KEK 역할을 해요. 스코프의 root KEK와 다양한 DEK(Data Encryption Key, 데이터 암호화 키)는 스코프가 생성될 때 만들어져요. DEK는 스코프의 root KEK로 암호화되고, 이는 다시 root 목적으로 표시된 KMS 키로 암호화돼요.

자체 관리형 Enterprise 배포에서는 root KMS 키를 구성할 수 있어요.

현재의 스코프별 DEK와 그 목적은 아래와 같아요.

DEK 목적 무엇을 암호화하나
audit 이벤트 로그의 비밀 값. 이벤트 로그에 대한 자세한 내용은 events 설정을 참고해요.
database 데이터베이스 안의 값을 암호화하는 범용 DEK. 일반적으로 비밀로 간주되는 값(API 키, 타사 토큰, 인증서 개인 키 등)을 암호화해요.
oidc 쿠키와 인증 요청의 OIDC 정보.
oplog 주어진 스코프의 oplog(작업 로그) 값.
tokens 주어진 스코프 안의 인증 메서드가 생성한 토큰.
sessions 세션별 암호화 키를 파생하는 기준 키로 사용.

키 버전 수명주기 관리 (Key version lifecycle management)

CLI나 API의 scopes 섹션 아래에 있는 키 엔드포인트를 사용해 스코프별 KEK와 DEK의 수명주기를 제어할 수 있어요. 스코프의 모든 키를 회전하려면 rotate-keys 엔드포인트를 사용해요.

$ boundary scopes rotate-keys -scope-id p_A4jfDjZ9jf

이 엔드포인트는 스코프 p_A4jfDjZ9jf의 모든 키에 대해 새 키 버전을 만들고, 이 키 버전을 새 데이터를 암호화하는 활성 키 버전으로 만들어요. 이전 키 버전은 기존 데이터를 복호화하는 데 계속 사용돼요. -rewrap 플래그를 쓰면 모든 DEK 버전을 새 KEK 버전으로 즉시 다시 래핑할 수 있어요. 그렇지 않으면 DEK 버전은 생성된 시점의 이전 KEK 버전으로 계속 암호화된 상태로 남아요.

스코프의 모든 키와 그 버전을 나열하려면 list-keys 엔드포인트를 사용해요.

$ boundary scopes list-keys -scope-id p_A4jfDjZ9jf

키 버전을 파기하려면 destroy-key-version 엔드포인트를 사용해요.

$ boundary scopes destroy-key-version -scope-id p_A4jfDjZ9jf -key-version-id kdkv_tr6ZN8opYr

최신 키 버전은 파기할 수 없으므로, 최신 키 버전을 파기하려면 먼저 rotate-keys를 호출해서 새 키 버전 집합을 만들어야 해요. oplog 목적의 키 버전도 현재로서는 파기할 수 없어요.

키 버전 파기는 완료되기 전에 백그라운드 작업이 필요할 때가 있어요. 그 이유는 현재 데이터를 암호화하는 DEK 버전이 삭제되기 전에 각 목적의 최신 DEK 버전으로 그 데이터를 다시 암호화해야 하기 때문이에요. 이 재암호화 작업의 진행 상황은 list-key-destruction-jobs 엔드포인트로 모니터링할 수 있어요.

$ boundary scopes list-key-version-destruction-jobs -scope-id p_A4jfDjZ9jf

작업이 이 목록에서 사라지면 해당 키 버전이 파기되었고 기존 데이터가 재암호화되었음을 의미해요.

bsr KMS 키

bsr KMS 키는 세션 녹화에 필요해요. 컨트롤러 구성에 bsr 키를 추가하지 않으면 세션 녹화를 활성화하려 할 때 오류가 발생해요. 이 키는 녹화 데이터를 암호화하고 녹화의 무결성을 확인하는 데 사용돼요.

previous-root KMS 키

previous-root KMS 키는 새 root 키로 마이그레이션할 때 사용해요. 구성에 previous-root KMS 키를 추가하면 컨트롤러가 데이터베이스의 기존 정보를 복호화하는 데 그 키를 사용하도록 지시해서, KEK를 회전하고 다시 래핑하여 새 root 키로의 마이그레이션을 완료할 수 있게 해줘요.

자체 관리형 Enterprise 배포에서는 previous-root KMS 키를 구성할 수 있어요.

worker-auth KMS 키

worker-auth KMS 키는 워커를 컨트롤러에 인증하기 위해 컨트롤러와 워커가 공유하는 키예요. 이 메커니즘의 세부 사항은 Connections/TLS 페이지에서 찾을 수 있어요. 워커가 worker-led 또는 controller-led 방식으로 등록된 경우에는 이 키가 필요하지 않아요.

HCP 또는 Enterprise 배포에서는 worker-auth KMS 키를 구성할 수 있어요. 그러나 HCP 워커에 연결하는 첫 번째 워커 집합에는 worker-auth 키를 구성할 수 없어요.

downstream-worker-auth KMS 키

downstream-worker-auth KMS 키는 멀티 홉 워커 배포에서 컨트롤러에 직접 연결하지 않고 다른 워커에 연결하는 워커를 인증하는 데 사용돼요.

worker-auth가 컨트롤러와 워커 사이의 공유 키를 정의한다면, downstream-worker-auth는 업스트림 워커가 다운스트림 워커의 인증 토큰을 검증하는 데 사용하는 키를 정의해요. 다운스트림 워커는 동일한 키 자료를 가리키는 worker-auth KMS 구성을 사용하고, 업스트림 워커는 일치하는 downstream-worker-auth 구성을 사용해요.

키의 특징은 다음과 같아요.

  • 스코프(Scope) — downstream-worker-auth 키는 워커-워커 인증 동안에만 사용돼요. Boundary 데이터베이스 레코드, 세션, 또는 다른 애플리케이션 데이터를 암호화하는 데는 사용되지 않아요.
  • 신뢰 도메인(Trust domains) — 각 키나 키 별칭은 일반적으로 특정 네트워크 세그먼트나 환경 같은 다운스트림 워커 집합에 대한 논리적 신뢰 도메인을 나타내요.
  • 업스트림당 여러 키(Multiple keys per upstream) — 업스트림 워커는 여러 downstream-worker-auth KMS 블록을 구성해서, 각각 자체 키를 가진 여러 신뢰 도메인의 다운스트림 워커를 받아들일 수 있어요.

worker-auth 및 worker-auth-storage와의 관계

Boundary는 워커 인증과 관련된 세 가지 KMS 목적을 사용해요.

  • worker-auth — worker-auth 키는 컨트롤러와 워커 사이, 또는 업스트림과 다운스트림 워커 사이에서 공유되어 워커 자체를 인증해요.
  • downstream-worker-auth — downstream-worker-auth 키는 업스트림 워커에만 구성돼요. 일치하는 worker-auth 구성을 사용해 인증하는 다운스트림 워커를 검증하는 데 사용돼요.
  • worker-auth-storage — worker-auth-storage 키는 controller-led 또는 worker-led 흐름으로 등록하는 워커가 저장된 자격 증명을 디스크에 암호화하는 데 사용해요. 외부 KMS로 등록된 워커는 사용하지 않아요.

worker-auth나 downstream-worker-auth로 KMS 주도 인증을 사용하는 워커는 worker-auth-storage를 사용하지 않아요. 디스크에 저장된 장기 활성 토큰에 의존하는 대신 각 연결에서 KMS에 대해 재인증하기 때문이에요.

recovery KMS 키

recovery KMS 키는 클라이언트가 Boundary 안의 거의 모든 작업을 인증하는 데 사용할 수 있는 구조/복구 작업에 사용돼요. 작동 방식은 클라이언트와 컨트롤러 사이에 공유 KMS를 사용한다는 점에서 인증 측면에서 worker-auth 흐름과 매우 유사해요. nonce와 생성 시간이 암호화된 페이로드로 포함되어 토큰 형식으로 만들어져 컨트롤러로 보내져요. 시간과 nonce는 공격자가 값을 재생할 수 없도록 하고, 각 작업이 클라이언트에 의해 개별적으로 인증되어야 하므로 KMS에 대한 접근을 철회하면 즉각적인 결과가 나오도록 보장해요.

자체 관리형 Enterprise 배포에서는 recovery KMS 키를 구성할 수 있어요.

참고: 이 kms 구성 블록이 컨트롤러 구성 파일에 존재할 필요는 없어요. 실제로 필요할 때를 제외하고는 빼 두는 것이 모범 사례며, 구성 파일 수정이 승인되도록 변경 제어 기능을 사용해야 해요. 더 이상 필요하지 않으면 블록을 제거해야 해요.

클라이언트 쪽에서 사용자는 CLI의 어떤 작업에서든 -recovery-config 플래그를 사용해서 적절한 kms 블록이 들어 있는 구성 파일을 지정할 수 있어요. 이 기능은 Go SDK에서도 접근할 수 있어요.

이 메커니즘으로 인가된 요청은 사용자를 u_recovery로 표시해요. 이 메커니즘은 고유하게 식별하는 사용자 정보가 없으므로 세션을 인가하는 데 사용할 수 없어요.

이 메커니즘이 유용한 다른 상황도 있어요. 예를 들어 Terraform 공급자의 일부 기본값과 함께 이 메커니즘을 사용해서, 삭제할 수 없는 리소스(내장 익명(u_anon), 인증(u_auth), 복구(u_recovery) 사용자와 global 스코프)를 제외한 Boundary의 모든 것이 Terraform을 통해 만들어지도록 보장할 수 있어요. 기본 리소스 생성을 건너뛰는 옵션으로 Boundary를 초기화하면, Terraform이 필요한 특정 리소스를 대신 만들 수 있고 recovery KMS로 초기 인증 메서드를 설정하는 것을 인증해요.

config KMS 키

이 키는 Boundary 구성 파일 안의 값을 암호화하는 데 사용할 수 있어요. 이 블록을 Boundary와 운영자 사이에 공유하면, 운영자가 민감하거나 비밀인 값(예: KMS용 클라우드 API 키)을 Boundary 구성 파일에 넣고 boundary config encrypt로 파일을 암호화한 다음 변경 제어 시스템에 안전하게 전달할 수 있어요. 그 KMS에 접근할 수 있는 다른 운영자나 시스템만 값을 복호화할 수 있어요. Boundary는 시작 시 config KMS 블록을 확인하고, 존재하면 시작 시점에 발견된 암호화된 값을 복호화하는 데 사용해요.

자체 관리형 Enterprise 배포에서는 config KMS 키를 구성할 수 있어요.

이 페이지에 설명된 다른 키들과 달리 config 키는 Boundary가 저장하는 데이터를 보호하지 않아요. Boundary가 읽기 전에 구성 파일 자체를 보호하죠. 그 결과 config 키는 운영자와 Boundary 서버가 모두 접근해야 하는 유일한 키예요. 운영자는 값을 암호화하는 데 사용하고, Boundary는 시작 시 그것들을 복호화하는 데 사용해요.

config KMS 키를 언제 사용하나요

구성 파일에 평문으로 저장할 수 없는 값이 있고, 그 파일 자체가 완전히 제어할 수 없는 곳에 있어야 한다면 config KMS 키를 고려해요. 흔한 경우는 다음과 같아요.

  • 구성 파일을 버전 관리에 커밋하는 경우.
  • 구성 관리 시스템을 통해 구성을 배포하는 경우.
  • CI/CD 파이프라인에서 아티팩트에 구성을 빌드하는 경우.

구성 값을 암호화하는 것은 구성 파일에 대한 접근을 제한하는 대체물이 아니에요. KMS에 닿을 수 없는 사람이 파일을 읽지 못하게 함으로써 노출 범위를 좁혀줄 뿐이에요.

보안 고려 사항 (Security considerations)

구성을 저장하고 배포하는 방법을 계획할 때 config 키의 다음 특성을 고려해요.

  • 키 접근이 누가 값을 읽을 수 있는지 정의 — config KMS에 닿을 수 있는 모든 운영자나 시스템은 파일을 복호화할 수 있어요. 따라서 KMS에 대한 접근은 구성 안의 비밀에 대한 접근과 동등해요.
  • Boundary는 시작 시 키가 필요해요 — Boundary가 KMS에 닿을 수 없으면 값을 복호화할 수 없고 시작하지 않아요. config KMS를 서버의 가용성 경로의 일부로 취급해요.
  • 키를 보호하는 파일 밖에 두어요 — 키가 같은 구성 파일에 기록된 aead 블록은 파일을 가진 사람이라면 누구나 키도 가지므로 아무 보호도 제공하지 않아요. 클라우드 KMS 공급자를 사용하거나 config 블록을 별도 파일에 두어요.
  • config 키는 Boundary의 다른 키와 독립적 — 회전하거나 교체해도 root, worker-auth, bsr 키에는 영향을 주지 않으며, 키 버전 수명주기의 일부가 아니에요.

config KMS 키로 값을 암호화하려면 구성 값 암호화를 참고해요.

더 알아보기 (Learn more)