
오늘 알게 된 건데, 의외로 모르는 분 꽤 많더라. External Secrets Operator(ESO) 쓰면서 ClusterSecretStore를 그냥 kind: ClusterSecretStore만 박아두고 끝내는 경우. 그러면 클러스터 안의 모든 네임스페이스가 그 SecretStore를 참조할 수 있게 된다. 즉, Vault나 AWS Secrets Manager로 가는 인증 경로가 사실상 클러스터 전체에 열려 있는 셈이다.
ESO 공식 문서의 보안 베스트 프랙티스에서도 ClusterSecretStore와 ClusterExternalSecret는 cluster-scoped라 특히 조심하라고 강조한다. 근데 막상 helm chart로 깔고 나면 example manifest를 그대로 복붙해서 쓰니까 이 부분이 묻히기 쉽다.
SecretStore vs ClusterSecretStore, 언제 뭘?
간단하게 정리하면:
- SecretStore (namespaced) — 팀/서비스 단위로 secret backend 인증을 분리하고 싶을 때. 팀마다 IRSA role 또는 Vault role이 다른 멀티 테넌트 환경에서 거의 강제된다.
- ClusterSecretStore (cluster-scoped) — 전 클러스터가 같은 backend(같은 인증 주체)로 가도 무방한 경우. 운영 클러스터 단일 테넌트라거나, 플랫폼팀이 모든 secret 접근을 한 곳에서 통제하는 모델.
사실 이게 좀 애매한데, 우리 팀에서는 "ClusterSecretStore + namespace 화이트리스트" 조합으로 가는 편이다. SecretStore를 네임스페이스마다 깔면 IRSA role도 매번 만들어야 해서 운영 부담이 커지고, 그렇다고 ClusterSecretStore를 풀어두기는 찜찜하니까 중간 절충점.
namespaceSelector로 잠그기
핵심은 spec.conditions에 namespaceSelector 또는 namespaces 화이트리스트를 거는 거다.
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-sm-prod
spec:
provider:
aws:
service: SecretsManager
region: ap-northeast-2
auth:
jwt:
serviceAccountRef:
name: eso-sa
namespace: external-secrets
conditions:
- namespaceSelector:
matchLabels:
eso.io/tier: prod
- namespaces:
- payment
- order
이렇게 해두면 eso.io/tier=prod 라벨이 붙은 네임스페이스, 그리고 명시적으로 적힌 payment/order만 이 SecretStore를 사용할 수 있다. 다른 네임스페이스에서 ExternalSecret이 이 store를 참조하면 ESO가 거부한다.
라벨 기반으로 가면 새 네임스페이스 추가할 때마다 manifest 수정할 필요가 없어서 편하다. 대신 라벨을 마음대로 붙이지 못하도록 Kyverno나 OPA Gatekeeper로 eso.io/tier 라벨 추가에 대한 정책을 거는 게 보통.
한 가지 더, refresh interval과 캐시
올해 4월쯤에 ESO 쪽에서 ClusterSecretStore의 caller cache 관련 이슈가 화제가 됐었다. ClusterSecretStore를 여러 ExternalSecret이 공유하다 보니 provider client가 캐시에 묶여 있어서, secret backend 쪽 credentials을 회전해도 ESO 캐시가 살아 있어서 즉시 반영이 안 되는 케이스. refreshInterval을 짧게 잡거나 ESO를 한 번 재시작해서 캐시를 비우는 식으로 대응한다.
운영 환경이라면:
- 너무 짧게(예: 10s) 잡지 말 것 — provider API rate limit 걸린다
- 보통
1m~5m사이에서 secret 종류별로 조정 - 정말 즉시 반영해야 하는 secret은 ExternalSecret 단위로 별도 짧은 interval
마무리
ESO를 쓴다면 ClusterSecretStore에 conditions 빠져 있는지 한 번 확인해 보시길. 그리고 이게 적용돼도 본질적인 secret 접근권한은 IRSA role이나 Vault policy 단에서 한 번 더 걸어두는 게 안전하다. namespaceSelector는 어디까지나 ESO 레벨의 가드일 뿐이라.
'IT > DevSecOps' 카테고리의 다른 글
| Kyverno cluster policy 하나 올렸다가 API 서버가 죽은 새벽 (0) | 2026.05.27 |
|---|---|
| cert-manager로 Wildcard 인증서 자동화하기 (운영하며 만난 함정들) (0) | 2026.05.24 |
| Tetragon vs Falco, 런타임 보안 뭘 쓸까 (0) | 2026.05.21 |
| OpenBao 내부 들여다보기 - 포크 이후 2년, 진짜로 Vault를 대체할 수 있나 (0) | 2026.05.20 |
| Cosign vs Notation, 우리 팀은 어떻게 골랐나 (0) | 2026.05.18 |