Files
project-gitops/docs/architecture/secret-trust.md
T

5.6 KiB

Secret trust boundaries

Dev Vault

dev-k3s는 workload 클러스터 안의 단일 self-hosted Vault를 사용합니다. 별도 Transit Vault는 두지 않습니다. Vault는 다음 API 객체를 제공합니다.

  • KV-v2 runtime secret path
  • Kubernetes auth와 workload role
  • Dynamic PostgreSQL credential
  • 애플리케이션 JWT signing용 Transit key

Dev Vault는 Shamir 1-of-1로 한 번 초기화하고 재시작 때 명시적으로 unseal합니다. 이는 폐기 가능한 개발 환경 전용입니다. Production에서는 managed Vault 또는 독립 failure domain의 HA integrated-Raft와 KMS/HSM auto-unseal이 필요합니다.

Three Terraform states

vault-foundation
  -> mounts/auth configuration
  -> delegated automation policies
  -> optional, separated CI JWT login roles

vault-workloads
  -> workload policies and Kubernetes auth roles
  -> project-auth-jwt Transit key

vault-database
  -> auth-system PostgreSQL connection
  -> auth-db-migration-dev dynamic role

vault-foundation은 routine runner가 아니라 bootstrap 또는 승인된 보안 관리자가 실행합니다. 이 state가 workloads/database automation policy를 만들고, OIDC/JWT trust가 설정됐을 때만 두 login role을 분리해 만듭니다. Workloads/database exact claim map은 최소 한 공통 discriminator key에서 다른 값을 가져야 합니다. 실제 issuer가 그 repository/ref/job claim을 신뢰할 수 있게 발행하는지 확인하지 못하면 CI JWT auth를 활성화하지 않습니다. Delegated state는 자신에게 권한을 추가할 수 없고 맡은 정확한 Vault API path만 변경합니다.

Exact API path 허용이 runner를 완전한 sandbox로 만들지는 않습니다. vault-workloads runner가 허용된 ACL policy 내용이나 Kubernetes auth role payload를 악의적으로 바꾸면 더 강한 policy를 연결하는 권한 상승이 가능합니다. 따라서 이 runner는 신뢰된 security automation으로 취급하고, protected branch, policy lint, saved-plan 승인과 Vault audit log를 함께 trust boundary로 사용합니다.

세 state는 terraform_remote_state로 연결하지 않습니다. Policy/role 이름은 checked-in contract로 공유하고 runbook 또는 CI stage가 실행 순서를 보장합니다.

Provider token과 PostgreSQL password는 ephemeral/write-only 입력으로만 전달합니다. KV payload는 Terraform resource/data source로 읽거나 쓰지 않습니다.

KV ownership paths

Secret path는 repository taxonomy와 같은 owner를 표현합니다.

Consumer Vault CLI path
PostgreSQL bootstrap kv/dev/systems/auth-system/postgres/superuser
Auth database bootstrap/runtime kv/dev/systems/auth-system/postgres/auth-server
Keycloak database kv/dev/systems/auth-system/postgres/keycloak
Keycloak bootstrap admin kv/dev/systems/auth-system/keycloak/bootstrap-admin
Auth-server Keycloak client kv/dev/workloads/auth-server/keycloak-client

Vault ACL과 Agent annotation은 KV-v2 API path인 kv/data/...를 사용합니다. CLI의 vault kv putkv/dev/...를 사용합니다. 이전 kv/dev/platform/... 값은 migration source이며 새 policy가 계속 허용하면 안 됩니다.

Workload authentication

Workload는 audience vault, TTL 1시간의 projected ServiceAccount token으로 Vault Kubernetes auth에 로그인합니다. Token은 Vault Agent가 사용하며 application container에 Kubernetes bearer token을 직접 노출하지 않습니다.

Role은 ServiceAccount, namespace, audience, token policy와 TTL을 정확히 묶습니다. 현재 role은 Project Auth backing service의 auth-system-dev와 Vault를 사용하는 auth-dev ServiceAccount에만 존재합니다. api-dev에는 Vault role도 Vault NetworkPolicy ingress도 없으며 필요가 생기기 전에는 권한을 추가하지 않습니다.

Secret 값은 승인된 운영자가 Vault에 직접 기록합니다. 값은 Git, Gitea Actions log, Terraform state, Kubernetes manifest에 남기지 않습니다.

Bootstrap material

Vault init output은 기본적으로 .local/vault/dev-k3s-init.json에 mode 0600으로 생성됩니다. Encrypted custody로 이동한 뒤 working copy를 제거합니다.

Initial root token은 다음 작업에만 사용합니다.

  1. vault-foundation apply
  2. OIDC/JWT가 없는 빈 lab의 짧은 TTL bootstrap token 발급과 capability 검증
  3. 최초 runtime secret seed
  4. 필요한 break-glass/recovery 절차 확인

vault-database 적용까지 끝나면 replacement token의 대표 update capability와 root policy 부재를 확인한 뒤 initial root와 bootstrap token을 폐기합니다. 상시 cluster ServiceAccount에 broad platform-admin 정책을 연결하지 않습니다. vault-workloadsvault-database의 routine 실행은 각각 짧은 TTL identity를 사용합니다.

Initial root 폐기 뒤에는 상시 foundation administrator가 없습니다. Future foundation 변경은 encrypted unseal custody의 승인을 받아 Vault generated-root ceremony를 수행하고, 승인된 plan 적용 뒤 생성한 root를 즉시 폐기해야 합니다.

Sealed Secrets는 private GHCR pull credential에만 사용합니다. Controller private key는 Git과 분리된 recovery custody에 백업합니다.

Dev limitations

  • Vault, PostgreSQL, ingress가 TLS를 사용하지 않음
  • Single-node Vault와 PostgreSQL
  • Kubernetes API egress CIDR가 현재 dev cluster에 종속
  • 정적 bootstrap secret은 coordinated rotation 필요
  • Namespace/path migration이 아직 실제 cluster에 적용되지 않음

이 제약은 production에서 허용되지 않습니다.