Короткий ответ
Kubernetes Secret хранит конфиденциальные данные отдельно от ConfigMap и ограничивает доступ через RBAC, но по умолчанию значение закодировано только в base64 — это кодирование для удобства передачи, а не шифрование, и без дополнительных мер (encryption at rest) секрет читается в открытом виде.
Как это работает подробнее
ConfigMap и Secret имеют одинаковую структуру (пары ключ-значение), но Secret предполагает более строгие ограничения доступа через RBAC и не выводится полностью в некоторых командах kubectl describe. Однако сами данные в etcd по умолчанию хранятся в base64, что легко декодируется (base64 -d) любым, кто получил доступ к объекту или к etcd.
Пример кода
security-example-443.sh
kubectl get secret db-credentials -o jsonpath='{.data.password}'
U3VwZXJTZWNyZXQxMjM=
echo 'U3VwZXJTZWNyZXQxMjM=' | base64 -d
SuperSecret123Что использовать на практике
- Практика. для реальной защиты включают encryption at rest для etcd (EncryptionConfiguration), ограничивают RBAC на чтение Secret, используют внешние системы управления секретами (Vault, External Secrets Operator) для хранения и инжекта значений, а не хранят чувствительные данные напрямую в манифестах.
- Проверка. Ожидаемое поведение: любой пользователь с правом get на объект Secret может декодировать пароль одной командой — это демонстрирует, что base64 не защищает значение, и доступ к Secret нужно ограничивать RBAC и шифровать etcd.
Подводные камни
- Ошибка. считать Secret зашифрованным хранилищем «из коробки»; хранить Secret-манифесты в открытом виде в Git без sealed-secrets/SOPS; давать широкий RBAC-доступ на
get secretsвсем пользователям namespace.