Прокси для учётных данных — технические детали
Как работает прокси.
От чего он защищает. От чего нет.
Эта страница предназначена для специалистов по безопасности, тестировщиков на проникновение и инженеров, оценивающих модель угроз прокси. В ней описывается, что делает прокси на уровне протокола, где учётные данные находятся в памяти и какие поверхности атаки остаются.
Архитектура
Прокси представляет собой HTTPS MITM-прокси на основе CONNECT. ИИ-агент устанавливает переменную HTTPS_PROXY, указывающую на него. Когда агент выполняет HTTPS-запрос, прокси перехватывает TLS-соединение, проверяет заголовки запроса на наличие ссылок на учётные данные, разрешает их в хранилище Clavitor и перенаправляет запрос с внедрёнными учётными данными в вышестоящий API.
По умолчанию прокси прослушивает порт 127.0.0.1:1983 — это шаблон sidecar, где прокси и агент совместно используют хост. Для общих развёртываний (один прокси обслуживает несколько агентов в частной сети, контейнерный sidecar для нескольких рабочих нагрузок, выделенный хост прокси) интерфейс прослушивания настраивается через CLAVITOR_PROXY_LISTEN.
Прокси представляет собой автономный бинарный файл Go. Без CGO. Вся криптография протокола Clavitor проходит через каноническую реализацию на Rust, скомпилированную в WebAssembly и загружаемую через wazero при запуске.
Обработка TLS
Прокси генерирует самоподписанный корневой центр сертификации ECDSA P-256 при первом запуске, сохраняя его в каталоге бинарного файла с правами 0600. Для каждого вышестоящего хоста сертификат листа выпускается по запросу, подписывается этим центром сертификации и кэшируется в памяти с ограниченным вытеснением (1000 хостов). Сертификаты листа действительны в течение 24 часов и прозрачно перегенерируются в 23-часовую отметку, чтобы предотвратить истечение срока действия в середине сеанса.
Агент должен доверять корневому сертификату CA прокси. Экспортируйте его с помощью команды clavitor-proxy ca.
Исходящие соединения используют TLS 1.3 минимум с согласованием ALPN для HTTP/2 и HTTP/1.1. Системный пул сертификатов используется для проверки вышестоящих соединений. Нет закрепления сертификатов — прокси доверяет всему, чему доверяет ОС.
Учётные данные никогда не кэшируются, никогда не записываются на диск и никогда не хранятся дольше одного HTTP-запроса.
| Фаза | Где находятся учётные данные | Продолжительность |
|---|---|---|
| В состоянии покоя в хранилище | Шифротекст AES-GCM в базе данных хранилища | До удаления |
| При передаче в прокси | Зашифрованный TLS JSON-ответ от API хранилища | Один полный цикл HTTP-запроса |
| Расшифровано в прокси | Память процесса (строка Go в куче) | Один HTTP-запрос |
| Внедрено в вышестоящий запрос | Зашифрованные TLS байты в сети к вышестоящему сервису | Один HTTP-запрос |
Прокси хранит ключ расшифровки учётных данных агента (16 байт) в памяти в течение всего времени своей работы. Он загружается из зашифрованной конфигурации sidecar (формат CLV1) при запуске и очищается при корректном завершении работы. Ключ никогда не покидает процесс.
Конфигурация sidecar зашифрована с использованием AES-128-GCM и HMAC-SHA256 с использованием детерминированных ключей, полученных из статического начального значения. Это обфускация, а не конфиденциальность — граница безопасности определяется правами доступа к файлу (0600) и владением файлом. Формат CLV1 используется совместно прокси, CLI и расширением браузера.
Режимы разрешения
Режим 1 — явный плейсхолдер
Агент включает ссылку clavitor://Entry/field в заголовок запроса. Прокси ищет запись в хранилище по имени, извлекает её, расшифровывает указанное поле и заменяет плейсхолдер реальным значением.
Если поиск возвращает ноль или более одного результата, прокси возвращает 502 со стабильным кодом ошибки. Плейсхолдер никогда не удаляется и не передаётся как есть.
Режим 2 — совпадение URL
Когда плейсхолдер отсутствует, прокси запрашивает у хранилища записи, URL которых совпадает с вышестоящим хостом. Если существует ровно одно совпадение с распознаваемой структурой поля, прокси автоматически внедряет учётные данные.
Ноль совпадений → передача (без ожидания учётных данных). Множественные совпадения → 502 с руководством по устранению неоднозначности. Неизвестная структура поля → 502.
Дерево принятия решений детерминировано: плейсхолдер присутствует → разрешить или сбой. Плейсхолдер отсутствует → совпадение URL или передача. Нет пути молчаливого отката, когда неудачное разрешение приводит к передаче запроса вышестоящему сервису без учётных данных.
По умолчанию хранилище видит собственный идентификатор агента прокси при каждом запросе. Ограничения скорости, проверки области действия и записи в журнале аудита приписываются прокси.
Когда несколько агентов совместно используют один экземпляр прокси, плейсхолдер может включать идентификатор агента: clavitor://agentid@Entry/field. Прокси отправляет этот идентификатор агента в хранилище, которое применяет области действия и ограничения скорости этого агента и регистрирует доступ от его имени. Идентификатор агента — это 32-символьное шестнадцатеричное значение, отображаемое на странице сведений об агенте в пользовательском интерфейсе хранилища.
# Without agent ID — attributed to the proxy Authorization: Bearer clavitor://OpenAI/key # With agent ID — attributed to agent 0102030405060708090a0b0c0d0e0f10 Authorization: Bearer clavitor://0102030405060708090a0b0c0d0e0f10@OpenAI/key
| Развёртывание | Модель идентификации | Изоляция |
|---|---|---|
| Один прокси на агент | ID прокси = ID агента (по умолчанию) | Полная — отдельный бинарный файл, конфигурация, область действия, ограничения скорости |
| Общий прокси, без ID агента в URL | Все агенты используют ID прокси | Общая область действия и ограничения скорости |
Общий прокси + agentid@ в URL | Идентификация на основе агента | Область действия, ограничения скорости и аудит на основе агента |
Идентификатор агента в URL не является механизмом аутентификации — токен CVT прокси аутентифицирует соединение. Идентификатор агента определяет атрибуцию: чьи области действия применяются, чьи ограничения скорости учитываются, чей журнал аудита записывает доступ. Хранилище отклоняет неизвестные идентификаторы агентов с явным сбоем.
Сетевая безопасность
Защита SSRF
По умолчанию прокси блокирует вышестоящие соединения с частными сетями (RFC 1918), метаданными экземпляров облака (169.254.169.254), петлевыми, локальными каналами и диапазонами carrier-grade NAT. DNS разрешается первым; все возвращённые IP-адреса проверяются перед установкой TCP-соединения, закрывая окно TOCTOU при перенаправлении DNS.
Переопределите с помощью CLAVITOR_PROXY_ALLOW_PRIVATE=true для агентов, которые законно обращаются к частным API.
Привязка к цели
Целевой хост CONNECT фиксируется при установке туннеля и используется на протяжении всего срока его действия. Последующие запросы в рамках туннеля не могут перенаправляться на другой хост путём манипулирования заголовком Host. Несоответствие приводит к 502.
Это предотвращает установку агентом туннеля к api.openai.com с последующей отправкой запросов на internal-service.corp.
Обработка заголовков
Заголовки "hop-by-hop" удаляются из запросов и ответов в соответствии с RFC 7230 §6.1: Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, Proxy-Connection, TE, Trailers, Transfer-Encoding, Upgrade.
Заголовок Set-Cookie удаляется из вышестоящих ответов, чтобы предотвратить установку cookie в HTTP-клиенте агента вышестоящими серверами.
Тела запросов и ответов передаются без буферизации. Тела запросов по умолчанию ограничены 64 МБ (CLAVITOR_PROXY_MAX_BODY_MB). Тела ответов передаются без жёсткого ограничения; при превышении Content-Length 100 МБ выдаётся предупреждение в журнале.
В режиме совпадения URL прокси сопоставляет метки полей хранилища с HTTP-заголовками:
| Метка поля | Внедрённый заголовок |
|---|---|
key, apikey, api_key, token, secret, bearer, access_token | Authorization: Bearer <value> |
x-api-key, api-key | X-API-Key: <value> |
username + password (в паре) | Authorization: Basic base64(user:pass) |
| Всё остальное | Отклонено — ERR-PROXY-052 |
В режиме плейсхолдера агент контролирует, какое поле разрешается и куда оно направляется. Приведённое выше сопоставление применяется только к режиму совпадения URL.
Каждый сбой генерирует стабильный код ERR-PROXY-NNN. Эти коды являются частью публичного интерфейса прокси — агенты и операторы могут сопоставлять их для оповещения и отладки.
| Диапазон | Категория |
|---|---|
001–019 | Настройка (конфигурация, инициализация, генерация CA, WASM) |
020–029 | Жизненный цикл демона |
030–049 | Разрешение плейсхолдеров (URI clavitor://) |
050–069 | Внедрение по совпадению URL |
070–089 | Вышестоящий сервис / TLS |
Поля идентификации недоступны
Записи хранилища поддерживают три уровня шифрования. Поля, зашифрованные хранилищем, являются метаданными в открытом тексте. Поля, зашифрованные учётными данными, расшифровываются ключом агента. Поля, зашифрованные идентификационными данными, шифруются ключом, который сервер и прокси никогда не видели. Только владелец хранилища может расшифровать их с помощью своего аппаратного ключа безопасности.
Если плейсхолдер ссылается на поле, зашифрованное идентификационными данными, прокси возвращает ERR-PROXY-035. Нет отката, нет частичного результата. Поле архитектурно недоступно из прокси.
От чего прокси не защищает
Модель угроз прокси — это компрометация навыка или внедрение подсказки, которое заставляет аутентифицированного агента собирать учётные данные. Основными средствами защиты являются ограничения скорости для каждого агента в хранилище, квоты на уникальные записи и двухэтапная блокировка. Прокси добавляет точку принудительного применения на сетевом уровне, где учётные данные разрешаются для каждого запроса и никогда не хранятся агентом.
Прокси работает на той же машине, что и агент. Злоумышленник с root-доступом может читать память процесса, подключать отладчик или перехватывать трафик loopback. Прокси является уровнем внедрения учётных данных, а не границей аппаратной безопасности.
Если вышестоящий API возвращает учётные данные в своём ответе (например, конечная точка "whoami"), агент их видит. Прокси внедряет учётные данные в запросы, а не в ответы. Он не фильтрует то, что возвращается.
Ведение журнала
Прокси записывает одну строку для каждого принятого CONNECT и выдаёт строки ошибок для сбоев. Он никогда не записывает в журнал:
- Расшифрованные значения учётных данных
- Полные URL-адреса запросов (строки запроса могут содержать секреты — регистрируются только схема, хост и путь)
- Тела запросов или ответов
- Ключ расшифровки учётных данных или содержимое конфигурации sidecar
Когда прокси обнаруживает, что ответ 400 от вышестоящего сервиса содержит ключевые слова, связанные с аутентификацией (unauthorized, invalid token и т. д.), он записывает диагностическую подсказку, предполагающую, что внедрённые учётные данные могут быть устаревшими. Ответ передаётся без изменений.
Криптография
Вся криптография протокола Clavitor — расшифровка полей AES-GCM, вывод ключей HKDF, кодирование base62, создание токенов CVT, упаковка/распаковка конфигурации CLV1 — выполняется внутри одного модуля WebAssembly (clavis_crypto.wasm), загружаемого через wazero, чистого Go-рантайма WASM. Без CGO. Без реализации примитивов Clavitor на Go.
Модуль WASM скомпилирован из того же крейта Rust (clavis-crypto), который используется браузером, CLI и расширениями браузера. Один источник истины, один бинарный файл, одна поверхность аудита.
Прокси использует crypto/tls от Go для TLS-соединения и crypto/ecdsa для генерации сертификатов MITM. Это вопросы транспорта, а не операции протокола Clavitor.
Секреты (ключ расшифровки учётных данных, ID агента, ID устройства, URL хранилища) находятся в зашифрованной конфигурации CLV1 sidecar, записанной один раз во время clavitor-proxy init. Операционные параметры находятся в переменных окружения:
| Переменная | По умолчанию | Назначение |
|---|---|---|
CLAVITOR_PROXY_LISTEN | 127.0.0.1 | Интерфейс прослушивания. Установите 0.0.0.0 для общих развёртываний или конкретный IP-адрес интерфейса. |
CLAVITOR_PROXY_PORT | 1983 | Порт прослушивания |
CLAVITOR_PROXY_ALLOW_PRIVATE | false | Разрешить соединения с частными сетями (RFC 1918) |
CLAVITOR_PROXY_MAX_BODY_MB | 64 | Ограничение размера тела запроса |
CLAVITOR_PROXY_WRITE_TIMEOUT | 300 | Таймаут записи ответа в секундах |
CLAVITOR_CONFIG | (каталог исполняемого файла) | Переопределить путь к конфигурации sidecar |
Операционные параметры не являются секретами. Они не должны находиться в зашифрованной конфигурации. Они должны находиться там, где инструменты развёртывания уже управляют ими — в окружении.
Проведите собственный аудит.
Криптография представляет собой единый аудируемый артефакт WASM. Модель угроз задокументирована. Если вы найдёте что-то, что мы упустили, мы хотим услышать об этом.