Безпечні патерни передачі secret values у Kubernetes
Якщо коротко: секрет, який процес може прочитати, теоретично можна витягнути. Тому правильна ціль — не магічне “неможливо витягти”, а мінімізувати наявність static secrets, скоротити TTL, тримати дані в RAM якомога менше часу, і закрити шляхи attach/exec/debug.
1. Що не варто робити
Secret values в environment variables
Це дуже поширений патерн, але він слабший, ніж здається:
- env values можуть випадково потрапити в логи, stack traces, crash dumps;
- їх часто легко засвітити через діагностичні механізми застосунку;
- вони живуть увесь lifecycle процесу;
- багато команд сприймають
envяк “достатньо безпечно”, хоча це просто зручний transport, а не сильна runtime boundary.
Висновок: env vars — acceptable convenience pattern, але не best security pattern.
2. Кращий baseline: workload identity + external secret retrieval
Найздоровіший production-підхід сьогодні:
- pod отримує workload identity;
- застосунок або sidecar звертається до Vault / Secret Manager / Key Vault / IAM STS;
- отримує короткоживучі credentials;
- тримає їх у memory only;
- періодично refresh / rotate;
- не пише static values в pod spec, image або ConfigMap.
Це значно сильніше, ніж зберігати довгоживучі токени у Kubernetes Secrets і передавати їх через env.
3. Ще краще: dynamic secrets
Де можливо, секрети мають бути динамічними:
- тимчасовий DB user/password;
- тимчасові cloud credentials;
- short-lived certificates;
- lease / revoke / rotate механіка.
Переваги:
- навіть якщо credential витягнули, його вікно життя маленьке;
- менший blast radius;
- простіше робити revoke;
- не потрібно роками жити з одним shared password.
4. Якщо секрет усе ж треба покласти в pod
Порядок переваги такий:
- dynamic retrieval at runtime
- in-memory file / tmpfs volume
- Kubernetes Secret volume
- environment variables
Чому tmpfs / in-memory файл кращий за env:
- менше випадкового leakage в logs / stack traces;
- краще контрольований lifecycle;
- простіше обмежити доступ правами до файлу;
- легше організувати rotation.
Але чесно: якщо attacker уже має виконання всередині контейнера — він, найімовірніше, зможе це прочитати. Тому секрет delivery не можна розглядати окремо від runtime hardening.
5. Runtime hardening: без цього всі розмови про secret hygiene неповні
Щоб зменшити ризик витягання секретів, потрібно не лише правильно їх доставляти, а й закривати шляхи доступу до процесу:
- заборонити
kubectl execзайвим ролям; - заборонити
pods/attach,pods/portforward,pods/ephemeralcontainersбез дуже вузького доступу; allowPrivilegeEscalation: false;privileged: false;readOnlyRootFilesystem: true;- запуск під non-root;
- drop capabilities;
- seccomp / AppArmor / SELinux де доступно;
hostPID,hostIPC,hostNetwork= false;- мінімізувати service account token exposure;
- обмежити egress через NetworkPolicy.
Це вже не “секрети”, а platform engineering guardrails — але без них історія про “невитягувані env” просто несерйозна.
6. Практичний recommended pattern
Для більшості production систем я б рекомендував такий стек:
- workload identity
- Vault / cloud secret manager
- dynamic or short-lived credentials
- memory-only usage
- no exec / no debug by default
- strict RBAC + admission policies
- runtime hardening
- auditability around secret access
Це дає не магічну “невитягуваність”, а операційно сильну, реалістичну модель захисту.
7. Що варто запам’ятати
Правильне запитання не:
“Як зробити так, щоб секрет неможливо було витягнути?”
А ось таке:
“Як зробити так, щоб ми майже не мали static secrets, щоб вони жили коротко, були прив’язані до identity, не лежали в env без потреби, і щоб до workload не можна було просто так приаттачитись?”
Оце вже хороший DevSecOps framing.
References
Нижче — сильні референси, які варто читати не як маркетинг, а як дизайн-матеріал:
-
HashiCorp Vault — Dynamic Secrets
https://developer.hashicorp.com/vault/tutorials/get-started/understand-static-dynamic-secrets -
Kubernetes Good Practices for Secrets
https://kubernetes.io/docs/concepts/security/secrets-good-practices/ -
GKE Workload Identity Federation
https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity -
Amazon EKS IAM Roles for Service Accounts (IRSA)
https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html -
SPIFFE / SPIRE for workload identity
https://spiffe.io/docs/latest/spiffe-about/overview/ -
Vault Agent Injector examples for Kubernetes
https://developer.hashicorp.com/vault/docs/platform/k8s/injector -
Kubernetes Pod Security Standards
https://kubernetes.io/docs/concepts/security/pod-security-standards/ -
Google: Applying SRE to cybersecurity
https://cloud.google.com/blog/products/identity-security