# 🔐 Безопасность Секретов и отличие от Паролей - мастер-ключ, шифрование и общая архитектура.

3 июня 2026 г. · 9 мин. чтения

Когда вы отдаёте свои пароли, токены и ключи доступа во внешний сервис, главный вопрос — можно ли ему доверять. Поэтому мы решили показать, как устроена безопасность [Tuna Секретов](https://tuna.am/docs/secrets.md) изнутри: где хранится мастер-ключ, каким алгоритмом шифруются данные и — самое важное — что произойдёт, если нашу инфраструктуру взломают и утечёт вся база данных.

Коротко

Значения секретов шифруются **до** записи в базу алгоритмом **AES-256-GCM**. Ключ, которым их можно расшифровать, в базе **не лежит**. Утёкший дамп БД без мастер-ключа — это бесполезный набор зашифрованных данных.

## Пароли и секреты: две разные модели безопасности

В Tuna есть два хранилища для чувствительных данных — [Менеджер паролей](https://tuna.am/docs/passwords.md) и [Секреты](https://tuna.am/docs/secrets.md). Они намеренно построены по-разному, потому что решают разные задачи.

![Сравнение моделей: пароли шифруются на клиенте, секреты — на сервере](/blog/img/2026-06-03-secrets-security/00-pwd-vs-secrets.png)

**Менеджер паролей — модель нулевого знания (zero-knowledge).** Ключи шифрования создаются на вашем устройстве и никогда не покидают клиент — браузер или приложение. Шифрование и расшифровка происходят только на вашей стороне, а на сервер уходит уже зашифрованный текст. Принцип, заложенный в основу: *компрометация нашей инфраструктуры не должна приводить к компрометации ваших паролей* — расшифровать их можно лишь там, где есть мастер-ключ, а он есть только у вас. Обратная сторона — данные доступны только владельцу мастер-ключа: автоматически выдать пароль скрипту или пайплайну, не раскрывая его, в такой модели невозможно.

**Секреты — серверное шифрование.** Здесь мастер-ключ находится на стороне платформы, и шифрование выполняет сервер. Это **осознанный компромисс**, и сделан он ради главного сценария секретов — автоматизации. Секрет должен сам, без участия человека, попадать в приложение при запуске, в CI/CD-пайплайн, в скрипт развёртывания. Запуск приложения с подгрузкой переменных, сервисные ключи для CI, автоматический перезапуск при изменении значения — всё это работает именно потому, что сервер способен выдать секрет по запросу авторизованного клиента, не требуя мастер-пароль каждый раз.

Платой за удобство становится доверие к инфраструктуре платформы — технически сервер может расшифровать секрет. Поэтому всё, что описано дальше, — про то, как мы это доверие оправдываем.

|                                | Пароли                    | Секреты                           |
| ------------------------------ | ------------------------- | --------------------------------- |
| Модель                         | Нулевое знание            | Серверное шифрование              |
| Где находится ключ             | Только у клиента          | На стороне платформы              |
| Где идёт шифрование            | На клиенте                | На сервере                        |
| Может ли Tuna прочитать данные | Нет                       | Да, для авторизованных операций   |
| Автоматизация (CI/CD, скрипты) | Ограничена                | Полноценная                       |
| Главный сценарий               | Хранение и обмен паролями | Доставка конфигурации приложениям |

## Модель доверия секретов

Раз сервер умеет расшифровывать секреты, главный принцип звучит так: **база данных не должна содержать ничего, чем можно расшифровать секреты**. Даже если у злоумышленника окажется полный дамп таблиц, в нём не должно быть достаточно материала, чтобы получить исходные значения.

Достигается это классической схемой **конвертного шифрования** (envelope encryption) — двухуровневой иерархией ключей.

## Конвертное шифрование: два уровня ключей

![Иерархия ключей: мастер-ключ оборачивает ключ команды, ключ команды шифрует значения секретов](/blog/img/2026-06-03-secrets-security/01-key-hierarchy.png)

В системе два уровня ключей:

1. **Мастер-ключ платформы (KEK, Key Encryption Key).** Хранится на стороне Tuna и в базу данных не попадает. Сам по себе он ничего пользовательского не шифрует — его единственная задача «оборачивать» (защищать) ключи команд.

2. **Ключ команды (DEK, Data Encryption Key).** Для каждой команды генерируется свой случайный ключ — криптографическим генератором случайных чисел. Именно им шифруются значения секретов этой команды.

Ключ команды не хранится в открытом виде: он зашифрован мастер-ключом и в таком «обёрнутом» виде лежит в базе. Чтобы им воспользоваться, сервер сначала разворачивает его мастер-ключом в памяти.

Получается цепочка зависимостей: **значение секрета** защищено **ключом команды**, а **ключ команды** защищён **мастер-ключом**. Разорвав любое звено, дальше пройти нельзя.

Любопытно, что [менеджер паролей](https://tuna.am/blog/password-manager.md) построен на той же идее конвертного шифрования — с двумя принципиальными отличиями: «конверт» там запечатывается асимметрично, на паре открытого и закрытого ключей, а корневой ключ остаётся на стороне клиента, а не сервера. Схема одна и та же, по-разному распределено лишь доверие: секреты настроены на автоматизацию, пароли — на нулевое знание.

## Где и как хранится мастер-ключ

Это основной для всей схемы вопрос, поэтому разберем каждое место хранения:

* **Не в базе данных.** Мастер-ключ принципиально отделён от данных, которые он защищает. В дампе базы его нет.
* **Не в коде и не в репозитории.** Он не зашит в исходники, а передаётся сервису извне — из защищённого хранилища конфигурации платформы.
* **Только в памяти процесса.** Сервер держит ключ в оперативной памяти на время работы и не пишет его на диск в открытом виде.
* **Полноценный 256-битный ключ.** Этого достаточно, чтобы перебор был вычислительно невозможен.

Главный вывод: **доступ к базе данных и доступ к мастер-ключу — это два разных уровня доступа** с разными правами. Компрометация одного из них не означает автоматически компрометацию второго.

## Жизненный цикл секрета: запись и чтение

Шифрование и расшифровка встроены в слой работы с данными и происходят прозрачно — приложение никогда не пишет открытое значение в базу и никогда не читает его оттуда напрямую.

![Последовательность сохранения и чтения секрета: шифрование перед записью, расшифровка после чтения](/blog/img/2026-06-03-secrets-security/02-lifecycle.png)

**При сохранении** значение шифруется ключом команды ещё до записи. Для каждого значения берётся свой случайный одноразовый вектор (nonce) — поэтому даже два одинаковых секрета выглядят в базе по-разному. В хранилище попадает только зашифрованный текст.

**При чтении** происходит обратный процесс: сервер достаёт шифр, разворачивает ключ команды и расшифровывает данные. Открытое значение существует только в памяти процесса ровно столько, сколько нужно, чтобы отдать его авторизованному клиенту.

Мы используем режим **GCM** (Galois/Counter Mode) — это *аутентифицированное* шифрование. Помимо конфиденциальности оно гарантирует целостность: если кто-то изменит хотя бы один байт зашифрованных данных в базе, расшифровка не вернёт «мусор», а честно провалится с ошибкой проверки. Подделать или незаметно подменить значение в обход сервера не получится.

В транзите всё дополнительно защищено TLS — между вашим клиентом и API данные идут по зашифрованному каналу.

## Что лежит в базе зашифровано, а что открыто

Разбор того, какие данные и в каком виде реально хранятся в базе:

| Зашифровано (AES-256-GCM)       | В открытом виде                             |
| ------------------------------- | ------------------------------------------- |
| Значения секретов               | Имена переменных                            |
| Заметки к секретам              | Типы значений                               |
| Ключ команды (в обёрнутом виде) | Уровень видимости                           |
|                                 | Структура: проекты, окружения, конфигурации |
|                                 | Метки времени создания и изменения          |

Да, **метаданные — это тоже информация**. Даже не видя значений, по именам переменных можно судить о том, какими сервисами и технологиями вы пользуетесь. Сами секреты при этом остаются зашифрованными. Но это снова небольшой компромисс в угоду удобству и быстроте работы.

## Что будет, если утечёт база данных

Это сценарий, ради предотвращения которого вся схема и строилась. Представим худшее: злоумышленник получил полный дамп нашей базы.

![Модель угроз при утечке базы: без мастер-ключа расшифровать значения невозможно](/blog/img/2026-06-03-secrets-security/03-db-leak.png)

**Что у него на руках:**

* Зашифрованные значения секретов — шифр AES-256-GCM, статистически неотличимый от случайного шума.
* Ключ команды — но он сам зашифрован мастер-ключом.
* Метаданные — имена, типы, структура проектов.

**Чего у него нет:**

* **Мастер-ключа.** Его нет в базе — он на стороне сервера, куда дамп базы доступа не даёт.

Цепочка обрывается на первом же шаге. Чтобы расшифровать значение, нужен ключ команды. Чтобы развернуть ключ команды — нужен мастер-ключ. Мастер-ключа в дампе нет, а взломать AES-256 перебором невозможно. **Значения секретов остаются защищены.** Злоумышленник видит лишь каркас: имена и структуру, но не содержимое.

### Границы защиты

Никакая схема не защищает от всего, и важно понимать её рамки:

* **Если утечёт И база, И мастер-ключ одновременно** — защита падает. Именно поэтому они хранятся раздельно, с разными правами доступа: чтобы одна уязвимость не вскрывала сразу оба уровня.
* **Метаданные видны** при утечке базы — об этом сказано выше.
* **Реакция на инцидент.** При подозрении на компрометацию правильный шаг — ротация: смена мастер-ключа, перевыпуск [сервисных ключей](https://tuna.am/docs/secrets.md) и обновление самих секретов в их первоисточниках. Сервисные ключи можно выпускать с ограниченным сроком жизни именно на такой случай.

## Дополнительные уровни защиты

Шифрование — это фундамент, но не единственный слой. Доступ к секретам ограничен ещё на нескольких уровнях:

* **Скрытые значения (Restricted).** Секрет с такой видимостью не отдаётся через API и не попадает в выгрузки — даже авторизованному пользователю показывается только факт его существования.
* **Сервисные ключи с узким доступом.** Для CI/CD выпускаются ключи, привязанные к конкретной конфигурации, с правами только на чтение или на чтение и запись, и с опциональным сроком действия. Утечка такого ключа не открывает доступ ко всем секретам команды.
* **Ограничение по IP (Trusted IP).** Доступ к конфигурации можно ограничить списком разрешённых адресов и подсетей в формате CIDR.
* **Полный аудит.** Все изменения внутри конфигураций журналируются — видно, кто и когда менял каждый секрет.

## Что в планах

Сейчас Tuna Секреты — это централизованное и зашифрованное хранилище. Логичный следующий шаг — сделать его **источником истины**, из которого секреты автоматически синхронизируются туда, где они нужны.

![Планы: синхронизация секретов из Tuna в Vault, Kubernetes Secrets, GitHub и GitLab CI/CD](/blog/img/2026-06-03-secrets-security/04-future-sync.png)

В планах — интеграции для односторонней синхронизации:

* **HashiCorp Vault** — отправка секретов в Vault, чтобы Tuna стала удобным интерфейсом управления, а приложения продолжали читать их привычным способом.
* **Kubernetes Secrets** — синхронизация конфигурации напрямую в секреты нужного namespace кластера.
* **GitHub Actions** — публикация в encrypted secrets репозитория или организации для использования в пайплайнах.
* **GitLab CI/CD** — синхронизация в CI/CD variables проектов и групп.

Идея в том, чтобы вы редактировали секрет в одном месте, а он автоматически и безопасно доходил до всех ваших окружений — без копирования значений между десятком панелей.

## Итог

Безопасность Tuna Секретов держится на нескольких простых и проверенных принципах:

* **Две модели под две задачи** — пароли шифруются на клиенте (мы их не видим), секреты — на сервере, ради автоматизации.
* **AES-256-GCM** — аутентифицированное шифрование значений до записи в базу.
* **Конвертное шифрование** — мастер-ключ защищает ключи команд, ключи команд защищают данные.
* **Мастер-ключ отделён от данных** — его нет ни в базе, ни в коде, и утёкший дамп БД бесполезен.
* **Слои доступа сверху** — видимость, сервисные ключи, ограничение по IP и аудит.

Мы не делаем вид, что защита абсолютна, и открыто показываем её границы — потому что доверие строится на прозрачности, а не на маркетинговых обещаниях.

## Оставьте отзыв

Если вам нравится пользоваться Tuna, или наоборот вы недовольны чем либо, то пожалуйста [оставьте отзыв](https://my.tuna.am/?show_feedback=1).

![](/blog/img/2024-08-22/feedback.gif)

## Новости

Анонсы новых функций и статей публикуем в [Telegram-канале](https://t.me/tuna_am). Подписывайтесь, чтобы ничего не пропустить.

## Помощь

Мы ценим наших пользователей и детально изучаем все обращения, если у вас возникли проблемы с tuna – обязательно свяжитесь с нами одним из способов:

* [Электронная почта](mailto:info@tuna.am)
* [Telegram сообщество](https://telegram.me/+Kgbtt0_gJwI5ZmEy)

**Теги:**

* [security](https://tuna.am/blog/tags/security)
* [secrets](https://tuna.am/blog/tags/secrets)
* [tuna](https://tuna.am/blog/tags/tuna)
