128 lines
5.6 KiB
Markdown
128 lines
5.6 KiB
Markdown
# 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
|
|
|
|
```text
|
|
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 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가 사용하며
|
|
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-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
|
|
- Kubernetes API egress CIDR가 현재 dev cluster에 종속
|
|
- 정적 bootstrap secret은 coordinated rotation 필요
|
|
- Namespace/path migration이 아직 실제 cluster에 적용되지 않음
|
|
|
|
이 제약은 production에서 허용되지 않습니다.
|