RKE2 CySec Offline CA 운영자 Bootstrap¶
이 변경은 bloodbag-cysec Secret/PKI의 external material/issuer blocker를 해소하기 위한 operator-controlled offline CA를 제공한다. cert-manager/Vault/SOPS/ExternalSecrets가 없는 클러스터를 전제로, 새 플랫폼 설치 없이 최초 내부 동작 확인이 가능한 방식이다. 실제 민감 byte 생성과 cluster apply는 하지 않는다. generator/tool/runbook/tests/Draft PR까지만 제공한다.
전제와 타당성¶
- 클러스터에는 cert-manager/Vault/SOPS/ExternalSecrets가 없다(PR #80 조사). 따라서 외부 PKI issuer를 새로 설치하거나 승인받기 전까지는, 운영자가 통제하는 경로에서 offline root/intermediate CA로 leaf를 발급하는 방식이 유일하게 반복 가능한 경로다.
- repo에는 별도 crypto 정책이 없으므로 아래 기본값을 소스에 상수로 고정하고, 외부 승인 전 "repo 기본값"임을 명시한다.
Crypto 정책 (repo 기본값, 외부 승인 대기)¶
- key: ECDSA P-256 (
SECP256R1), 서명: SHA-256 - root: offline, 10년,
BasicConstraints CA:true pathlen=1 - intermediate: 5년,
CA:true pathlen=0(leaf만 서명) - leaf: 90일,
digitalSignature+serverAuth, rotation overlap 30일 (T-30 갱신) - password: 256-bit (
secrets.token_urlsafe(32)), 17개 (DB 5 + Redis 12) - root/intermediate key는
PBKDF2-HMAC-SHA256 + AES-256-CBC(BestAvailableEncryption)로 encrypted at rest, mode0400/nlink1/no symlink
경로·권한 경계¶
- root key는 Git/클러스터에 절대 저장하지 않는다. operator-controlled
--ca-dir에만 둔다. - key는
0400, cert는0444, material 파일은0400, 모두 nlink1·no symlink·O_EXCL|O_NOFOLLOW(TOCTOU 방지). - 모든 operator 입력(passphrase/token/username)은 파일로만 받는다. argv·env·stdout·log·history 노출 금지.
/proc/<pid>/environ노출을 피하기 위해 material은 env가 아닌 file로 공급한다.
명령¶
# 1) operator 입력 파일 준비 (권한 0600)
umask 077
printf 'root-passphrase' > /ops/cysec/root-pass
printf 'intermediate-passphrase' > /ops/cysec/inter-pass
printf 'ghcr-machine-user' > /ops/cysec/registry-user
printf 'ghcr-read-packages-token' > /ops/cysec/registry-token
printf 'bloodbag_migration' > /ops/cysec/migration-user
chmod 600 /ops/cysec/root-pass /ops/cysec/inter-pass /ops/cysec/registry-user /ops/cysec/registry-token /ops/cysec/migration-user
# 2) one-shot bootstrap (owner 필수, fail-closed)
infra-tools cysec-offline-ca bootstrap \
--ca-dir /ops/cysec/ca \
--material-dir /ops/cysec/material \
--material sites/tirosh-home/rke2/bloodbag-cysec-secret-pki-material.toml \
--owner <operator-email> \
--root-key-pass-file /ops/cysec/root-pass \
--intermediate-key-pass-file /ops/cysec/inter-pass \
--registry-username-file /ops/cysec/registry-user \
--registry-token-file /ops/cysec/registry-token \
--migration-user-file /ops/cysec/migration-user
# 3) 감사
infra-tools cysec-offline-ca verify --ca-dir /ops/cysec/ca --material-dir /ops/cysec/material \
--material sites/tirosh-home/rke2/bloodbag-cysec-secret-pki-material.toml
# 4) leaf rotation (overlap 30일)
infra-tools cysec-offline-ca rotate --ca-dir /ops/cysec/ca --material-dir /ops/cysec/material \
--material sites/tirosh-home/rke2/bloodbag-cysec-secret-pki-material.toml \
--intermediate-key-pass-file /ops/cysec/inter-pass
# 5) backup / manual secure cleanup
infra-tools cysec-offline-ca backup --ca-dir /ops/cysec/ca --archive /ops/cysec/ca-backup.tgz
# cleanup은 비활성화(fail-closed)되어 있다. 수동 secure deletion 수행.
bootstrap: offline root/intermediate/leaf(4) + password(17) + material directory(32 file)를 만든다. PostgreSQL bootstrapbloodbag-postgres-bootstrap/admin-password도 256-bit random password로 생성한다. nginx Ingress 전용 leafbloodbag-cysec-product-api-tls(SANcysec.bloodbag.internal.tirosh.ai)도 동일한 정책으로 발급된다.--owner가 없으면 non-zero로 종료한다(owner assignment를 source policy로 정할 수 없으므로 explicit input fail-closed).verify: chain(root self-signed → intermediate → leaf), SAN exact,serverAuth, key usage를 감사한다. 값을 읽지 않는다.rotate: intermediate로 새 leaf를 재발급한다. root는 offline 유지.backup: CA 디렉터리를0400archive로 복제한다. recovery는 archive를 operator 경로로 복원 후verify로 확인한다.cleanup: 비활성화(fail-closed). POSIX는 "최종 identity 확인 + 제거"를 원자적으로 제공하지 않아, 자동 overwrite-then-unlink가 확인한 member를 실제로 삭제함을 보장할 수 없다. 보장되지 않는 동작을 주장하는 대신 실행을 거부한다. 민감 material의 secure deletion은 운영자가 신뢰하는 수단(shred,srm등)으로 수동 수행해야 한다.
material 공급 (file-based adapter)¶
PR #80의 plan/apply에 --material-dir을 추가했다. env export 없이 descriptor-safe material directory에서 값을 읽는다.
infra-tools bloodbag-cysec-secret-pki plan \
--registration sites/tirosh-home/rke2/bloodbag-cysec-secret-pki-registration.yaml \
--material sites/tirosh-home/rke2/bloodbag-cysec-secret-pki-material.toml \
--material-dir /ops/cysec/material
파일은 env 이름(BLOODBAG_CYSEC_*) 그대로, mode 0400/nlink1/no symlink여야 하며, 빠지거나 잘못되면 fail-closed로 거부한다.
owner/runbook¶
- rotation owner와 runbook은 저장소 근거가 없으므로 blocked로 유지하고,
bootstrap --owner를 통한 explicit operator assignment를 필수로 받는다. - registry token은 GHCR PAT(운영자 제공)이며 generator는 임의 생성하지 않는다. migration
database-user도 운영자 입력이며, 정확히bloodbag-database-migration/database-user(BLOODBAG_CYSEC_DATABASE_MIGRATION_USER)에만 공급한다. legacybloodbag-product-backend-migrationmaterial은 생성하지 않으며,bloodbag_migrationprincipal은 계약상blocked로 유지한다.
현재 상태¶
- generator/tool/runbook/tests가 구현·검증되어 있다. 민감 byte 실생성과 cluster apply는 수행하지 않았다.
- 다음 단계는 외부 PKI/rotation 정책 승인 후, 위
bootstrap→verify→plan --material-dir→ PR #80apply순서로 진행한다.