refactor(gitops): establish platform ownership boundaries
This commit is contained in:
@@ -2,54 +2,126 @@
|
||||
|
||||
## Dev Vault
|
||||
|
||||
`dev-k3s`는 단일 self-hosted Vault를 사용합니다. 동일 workload
|
||||
클러스터에 별도의 Transit Vault를 두지 않습니다. 단일 Vault는 다음을
|
||||
소유합니다.
|
||||
`dev-k3s`는 workload 클러스터 안의 단일 self-hosted Vault를 사용합니다.
|
||||
별도 Transit Vault는 두지 않습니다. Vault는 다음 API 객체를 제공합니다.
|
||||
|
||||
- KV-v2 runtime secret path
|
||||
- Kubernetes auth와 workload role
|
||||
- dynamic PostgreSQL credential
|
||||
- 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을 사용해야 합니다.
|
||||
Dev Vault는 Shamir 1-of-1로 한 번 초기화하고 재시작 때 명시적으로
|
||||
unseal합니다. 이는 폐기 가능한 개발 환경 전용입니다. Production에서는
|
||||
managed Vault 또는 독립 failure domain의 HA integrated-Raft와 KMS/HSM
|
||||
auto-unseal이 필요합니다.
|
||||
|
||||
## Terraform
|
||||
## Three Terraform states
|
||||
|
||||
`vault-core` state는 mounts, auth, policies, roles와 JWT key를 소유하며
|
||||
제한된 관리자만 적용합니다. `vault-database`는 PostgreSQL connection과
|
||||
dynamic roles만 소유하고 `vault-database-automation-dev` 정책을 사용합니다.
|
||||
```text
|
||||
vault-foundation
|
||||
-> mounts/auth configuration
|
||||
-> delegated automation policies
|
||||
-> optional, separated CI JWT login roles
|
||||
|
||||
Terraform variable로 전달되는 token과 PostgreSQL password는 ephemeral/
|
||||
write-only 경계를 사용합니다. KV payload는 Terraform resource/data
|
||||
source로 읽거나 쓰지 않습니다.
|
||||
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 put`은 `kv/dev/...`를 사용합니다. 이전
|
||||
`kv/dev/platform/...` 값은 migration source이며 새 policy가 계속
|
||||
허용하면 안 됩니다.
|
||||
|
||||
## Workload authentication
|
||||
|
||||
workload는 audience `vault`, TTL 1시간의 projected ServiceAccount token으로
|
||||
Vault Kubernetes auth에 로그인합니다. token은 Vault Agent가 사용하며
|
||||
Workload는 audience `vault`, TTL 1시간의 projected ServiceAccount token으로
|
||||
Vault Kubernetes auth에 로그인합니다. Token은 Vault Agent가 사용하며
|
||||
application container에 Kubernetes bearer token을 직접 노출하지 않습니다.
|
||||
|
||||
Secret payload는 승인된 운영자가 Vault에 직접 기록합니다. 값은 Git,
|
||||
Gitea Actions log, Terraform state, Kubernetes manifest에 남기지 않습니다.
|
||||
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은 `vault-core`와 operator auth 검증 직후
|
||||
폐기합니다.
|
||||
`0600`으로 생성됩니다. Encrypted custody로 이동한 뒤 working copy를
|
||||
제거합니다.
|
||||
|
||||
Sealed Secrets는 private GHCR pull credential에만 사용합니다. controller
|
||||
private key는 별도 복구 저장소에 백업해야 합니다.
|
||||
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-workloads`와 `vault-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
|
||||
- Vault, PostgreSQL, ingress가 TLS를 사용하지 않음
|
||||
- Single-node Vault와 PostgreSQL
|
||||
- Kubernetes API egress CIDR가 현재 dev cluster에 종속
|
||||
- 정적 bootstrap secret은 coordinated rotation 필요
|
||||
- Namespace/path migration이 아직 실제 cluster에 적용되지 않음
|
||||
|
||||
이 제약은 production에서 허용되지 않습니다.
|
||||
|
||||
Reference in New Issue
Block a user