Безопасность
Здесь написано и то, что система гарантирует, и то, чего она не гарантирует. Второе — важнее.
Мы не zero-knowledge, и не будем это утверждать
В покое — только шифртекст: значения зашифрованы на ключе окружения, сам ключ — под корневым, который живёт вне базы. Украденный дамп без корневого ключа бесполезен.
Но живой процесс сервера видит значения, когда показывает их в дашборде и когда записывает. Машинный путь при этом честно клиентский: SDK получает шифртекст и ключ, обёрнутый под его identity, и расшифровывает у себя.
Ничего вечного
У client secret есть отзыв, у access-токена — TTL в минуты, у enrollment-токена — минуты и ровно одно использование. Корневой ключ тоже меняется: перешифровка затрагивает ключи окружений, а не значения, поэтому стоит порядка числа окружений.
Повтор — это сигнал, а не ошибка
Повторный обмен одноразового enrollment-токена и повторное использование ротированного refresh-токена означают, что секрет держат двое. Система не просто отказывает: она гасит сессии и поднимает событие с уведомлением администраторам.
Периметр
- ограничение частоты на вход и обмен токенов — по адресу и по субъекту;
- проверка адресов вебхуков от SSRF: дважды, при сохранении и перед каждой доставкой;
- лимиты размера запроса и значения — и в приложении, и на обратном прокси;
- refresh-токен браузера в httpOnly-cookie, access-токен только в памяти вкладки;
- CSP, HSTS и запрет фреймов на отдаче статики.
FAQ
- Это zero-knowledge?
- Нет. В покое хранится только шифртекст, и компрометация базы без корневого ключа секретов не раскрывает, но живой процесс сервера имеет доступ к значениям при показе в дашборде. Машинный путь при этом полностью клиентский.
- Что будет, если сервис недоступен?
- SDK держит значения в памяти процесса и переживает недоступность сервера до перезапуска: сервисы не падают вместе с нами. Аварийный выход всегда открыт — выгрузка окружения в обычный .env занимает одну команду CLI.
- Что мешает вам прочитать наши секреты?
- Технически — ничего: ключ шифрования хранится у нас, и в этом мы не отличаемся от любого управляемого хранилища. Отличается то, что видно вам: каждое чтение попадает в отдельный поток аудита с хеш-цепочкой, а значения с видимостью restricted не показываются в интерфейсе вообще — их получают только сервисы по своей identity.