Заметки о Kubernetes Security и DevSecOps

DevSecOps для самых маленьких: 3\n. Эндер-сундук. Секреты.

19 сентября 2026 г., 4 минуты

В Minecraft есть обычный сундук и эндер-сундук. Обычный стоит у тебя на базе: нашли базу, нашли координаты, выгребли всё. Эндер-сундук привязан к игроку: даже если базу найдут или тебя убьют, содержимое останется с тобой.

С секретами в DevSecOps то же самое. Kubernetes Secret, .env-файл, переменная в CI — обычные сундуки: любой с доступом к кластеру, репозиторию или пайплайну их откроет. Vault, Deckhouse Stronghold, StarVault — эндер-сундуки: централизованное хранилище с ролями, аудитом каждого чтения и ротацией. А Gitleaks — проверка перед выходом из дома: не оставил ли ты координаты базы на табличке у двери.

Сразу прививка для новичка: base64 — это не шифрование, а кодирование. Любой раскодирует его за секунду. Пароль в Git — это пароль, который уже утёк.

Я когда-то работал у вендора. Пароли лежали где угодно, только не в хранилище. Vault подняли за день, а секреты по разработчикам собирали неделю. Пароль от самой важной базы был pass_word1 и лежал в Dockerfile. Технически просто, организационно ад. Эта тема не про инструменты, она про людей.

Почему Kubernetes Secret — обычный сундук
Secret — штатный способ передать приложению конфигурацию, но не хранилище секретов. Данные в нём лишь закодированы base64. Если не включено шифрование etcd (базы, где Kubernetes хранит всё состояние кластера), они лежат там открытым текстом. Доступ ограничивается RBAC (правами доступа в кластере), а ротации и динамических учёток у Secret нет. Поэтому Secret — это способ доставить секрет в под, а не место, где его хранить.

Три уровня зрелости
Уровень 1. Гигиена: Gitleaks. Ищет секреты в коде и истории коммитов по регулярным выражениям и энтропии. Подключается в три приёма. 

  1. pre-commit hook ловит секрет до коммита:

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: <актуальный тег>   # возьми релиз и зафиксируй
    hooks:
      - id: gitleaks

    2. CI-задача страхует: hook можно не установить или обойти.

# .gitlab-ci.yml
gitleaks:
  stage: test
  image:
    name: ghcr.io/gitleaks/gitleaks:<версия>
    entrypoint: ['']
  variables:
    GIT_DEPTH: 0          # чтобы проверялась вся история, а не 20 коммитов
  script:
    - gitleaks detect --source . --redact --verbose

   3. Ротация. Если секрет попал в Git, отзови и замени его. git filter-repo или BFG уменьшат распространение, но не гарантируют, что копий не осталось: они бывают в форках, клонах и кэшах.


Уровень 2. Git-native: SOPS + age. Если хранилища ещё нет, а требования уже есть. SOPS шифрует значения в YAML, JSON и ENV, оставляя ключи читаемыми, поэтому зашифрованный файл можно хранить в Git. age — современный инструмент шифрования, ключи которого использует SOPS.

age-keygen -o key.txt                       # у каждого инженера своя пара
sops -e secrets.yaml > secrets.enc.yaml     # зашифровать
sops -d secrets.enc.yaml                    # расшифровать


# .sops.yaml: кому шифруем
creation_rules:
  - path_regex: .*secrets.*\.yaml$
    age: <публичный ключ получателя>


Самое сложное здесь — выдача и отзыв ключей. Если приватный ключ получателя утёк, он расшифрует всё, что шифровалось под него; смена ключа старые копии не защитит. В CI приватный ключ держи в защищённом хранилище CI.

Уровень 3. Централизованное хранилище. Отдельный сервис: секреты зашифрованы, доступ по ролям, аудит каждого чтения, ротация и динамические секреты (временная учётка в базе на 15 минут, потом она удаляется, а разработчик пароль вообще не видит). Это и есть эндер-сундук: Vault, его открытый форк OpenBao, российские Deckhouse Stronghold и StarVault.

С Kubernetes Vault интегрируется тремя способами. Agent Injector добавляет в под sidecar, который кладёт секреты в общий том. Vault Secrets Operator синхронизирует секреты в Kubernetes Secret. Secrets Store CSI Provider монтирует секреты в под, минуя Secret. Выбор зависит от того, как приложение читает секреты и нужна ли ротация на лету.

Российские решения
Deckhouse Stronghold от Флант — замена Vault, есть бесплатная Community Edition. Редакция CSE получила сертификат ФСТЭК № 5038 от 10 февраля 2026 года (приказ № 76, 4-й уровень доверия). Сертификат не значит, что продукт подходит для любой системы: вендор указывает конкретные классы и уровни защищённости, сверь их со своими. StarVault от Orion soft — интеграция с CI/CD и Kubernetes, аутентификация через JWT, OIDC, LDAP. Оба продукта проверь по реестру российского ПО.

Нюансы
Лицензия Vault. С августа 2023 новые версии выходят под BUSL 1.1, это не open source по версии OSI. Внутреннее использование разрешено; ограничения касаются предложения Vault третьим лицам как конкурирующего продукта. Через четыре года конкретная версия переходит на MPL 2.0. Если строишь на Vault коммерческий продукт, прочитай лицензию для своего сценария или смотри на OpenBao.
Флаги masked и protected в GitLab скрывают переменные в логах, но не защищают runner'ы. Контролируй, кто может запускать пайплайны.
План на практике
Неделя 1: Gitleaks в pre-commit, отозвать старые утечки. Неделя 2: Gitleaks в CI, критичные находки ломают сборку. Недели 3–4: SOPS + age для .env, Helm values и конфигов, если секреты должны жить в Git. Месяцы 2–3: выбрать хранилище, настроить Kubernetes-аутентификацию, включить аудит, перевести хотя бы базу на динамические секреты.

Чек-лист:

  • Gitleaks в pre-commit и в CI
  • Утёкшие секреты отозваны и заменены
  • .env не коммитятся, секреты в Git только зашифрованные
  • Включено шифрование etcd, RBAC ограничивает чтение Secret
  • Есть план ротации и выбрано хранилище


Секреты — фундамент: без них не работают ни харденинг, ни микросегментация, ни Policy as Code. Если пароль хоть раз побывал в Git, считай, что он утёк. Не надейся, что коммит удалили вовремя: отзывай и меняй. Всё остальное — попытка сделать вид, что сундук закрыт, пока ключ лежит под ковриком.

Обсуждаем статьи в Telegram-канале. Недушный ИнфоБез.

Social Media
Telegram
Powered by BS5 Simply Blog and Bludit
Navigation