Мы делаем proxykey — credential proxy: настоящие API-ключи лежат у нас зашифрованными, а приложения и ИИ-агенты ходят с отзываемыми виртуальными токенами. Недавно мы писали здесь про саму схему. Под ней и в личках всплыл один и тот же вопрос — самый правильный вопрос к любому такому сервису:
«А вы сами можете прочитать мои ключи?»
Короткий честный ответ: технически — да. И вместо того чтобы прятать это в маркетинговый туман, мы сделали две вещи: опубликовали крипто-модуль целиком и написали страницу с моделью угроз, где этот пункт стоит первым и жирным. Этот пост — о том, почему так, и что именно мы открыли.
Почему «zero-knowledge» здесь невозможен в принципе
Прокси обязан расшифровать ключ, чтобы подставить его в запрос к провайдеру — в этом вся его работа. Менеджер паролей может быть zero-knowledge: серверу ваш пароль не нужен. Credential proxy — не может: в момент запроса плейнтекст ключа существует в памяти процесса.
Из этого следует неудобная, но железная логика: процесс с полным доступом — а значит, и оператор сервера — в принципе способен получить открытый текст. Это свойство архитектуры, а не недоработка. И оно одинаково для всех hosted-решений этого класса — секрет-менеджеров, прокси, облачных хранилищ. Разница только в том, кто говорит об этом прямо.
Что тогда защищает шифрование
От вполне конкретных и куда более вероятных сценариев:
|
Сценарий |
Защищено? |
|---|---|
|
Утечка дампа БД |
✅ секреты зашифрованы, мастер-ключа в базе нет |
|
Кража бэкапов |
✅ те же шифртексты без ключа |
|
Слив логов |
✅ ключей и auth-заголовков в логах нет |
|
Компрометация только БД |
✅ без KEK из окружения процесса шифртексты бесполезны |
|
Утечка виртуального токена |
✅ привязка к IP, лимиты, отзыв в один клик |
|
Полная компрометация сервера / злонамеренный оператор |
❌ честно: нет |
Полная версия таблицы — на странице безопасности.
Что мы открыли
Репозиторий proxykey-crypto — ровно тот модуль конвертного шифрования, который шифрует секреты у нас в проде. 450 строк TypeScript вместе с тестами, без зависимостей кроме node:crypto:
-
на каждый секрет — свой DEK, плейнтекст шифруется AES-256-GCM с AAD = id секрета (шифртекст нельзя тихо переставить в чужую запись);
-
DEK обёрнут мастер-ключом (KEK), который живёт только в окружении процесса — в базе его нет;
-
расшифровка — в памяти на время одного запроса, DEK и копия плейнтекста зануляются в
finallyна любом пути, включая исключения; -
виртуальные токены в базе — только SHA-256-хэши;
-
18 тестов: roundtrip, подмена шифртекста/тега/обёртки, чужой AAD, неверная версия ключа.
Чего открытый код НЕ гарантирует
Тоже прямым текстом, потому что это вторая половина честности:
-
Открытый код — не доказательство. Вы можете отревьюить схему, но криптографически доказать, что на сервере исполняется именно этот код, репозиторий не может. Это жест прозрачности, не аттестация.
-
fill(0)— best-effort. V8 мог успеть скопировать буферы внутри своих операций; а строка с расшифрованным ключом в JS неизменяемая — её нельзя затереть, она живёт до сборщика мусора. Мы сузили окно, но не закрыли его — и говорим это вслух. -
Проверяется длина KEK, но не его энтропия. KDF там нет намеренно: мастер-ключ обязан быть случайным ключом (
openssl rand -base64 32), а не паролем.
В README репозитория есть раздел «Design notes» с ответами на стандартные вопросы ревьюеров — границы random-nonce для GCM, почему обёртка DEK не привязана к AAD (ради будущей ротации KEK), и так далее. Если найдёте, к чему придраться сверх этого — идите в issues, это лучший вклад в общую безопасность.
Как снизить даже «оператора»
Практичный остаток для тех, кто пользуется любым hosted-хранилищем ключей, не только нашим:
-
заводите скоуп-ключи, а не мастер-ключи: проектный ключ OpenAI с бюджетом $20 вместо ключа всего аккаунта — тогда даже полная компрометация хранилища стоит вам $20, а не всё;
-
ставьте лимиты на стороне провайдера — вторая линия после лимитов хранилища;
-
ротируйте оригиналы — перевыпуск у провайдера обнуляет ценность всего, что могло утечь раньше;
-
не доверяете вообще — рациональная позиция: схема воспроизводима, крипто-модуль открыт, соберите свою инсталляцию.
Диклеймер
Мы — авторы proxykey (proxykey.org). Сервис бесплатный. Пост — не «у нас безопасно, доверьтесь», а ровно наоборот: вот граница, до которой безопасно, вот код, вот что остаётся на доверии. Нам кажется, так честнее — и полезнее для всех, кто выбирает, где хранить ключи.
ссылка на оригинал статьи https://habr.com/ru/articles/1056134/