Прокси для учётных данных — технические детали

Как работает прокси.

От чего он защищает. От чего нет.

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

Архитектура

Прокси представляет собой HTTPS MITM-прокси на основе CONNECT. ИИ-агент устанавливает переменную HTTPS_PROXY, указывающую на него. Когда агент выполняет HTTPS-запрос, прокси перехватывает TLS-соединение, проверяет заголовки запроса на наличие ссылок на учётные данные, разрешает их в хранилище Clavitor и перенаправляет запрос с внедрёнными учётными данными в вышестоящий API.

По умолчанию прокси прослушивает порт 127.0.0.1:1983 — это шаблон sidecar, где прокси и агент совместно используют хост. Для общих развёртываний (один прокси обслуживает несколько агентов в частной сети, контейнерный sidecar для нескольких рабочих нагрузок, выделенный хост прокси) интерфейс прослушивания настраивается через CLAVITOR_PROXY_LISTEN.

illustration: unknown name=proxy-sequence

Прокси представляет собой автономный бинарный файл 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. Системный пул сертификатов используется для проверки вышестоящих соединений. Нет закрепления сертификатов — прокси доверяет всему, чему доверяет ОС.

Credential lifecycle

Учётные данные никогда не кэшируются, никогда не записываются на диск и никогда не хранятся дольше одного 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 или передача. Нет пути молчаливого отката, когда неудачное разрешение приводит к передаче запроса вышестоящему сервису без учётных данных.

Agent identity

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

Когда несколько агентов совместно используют один экземпляр прокси, плейсхолдер может включать идентификатор агента: 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 МБ выдаётся предупреждение в журнале.

Field-to-header mapping

В режиме совпадения URL прокси сопоставляет метки полей хранилища с HTTP-заголовками:

Метка поляВнедрённый заголовок
key, apikey, api_key, token, secret, bearer, access_tokenAuthorization: Bearer <value>
x-api-key, api-keyX-API-Key: <value>
username + password (в паре)Authorization: Basic base64(user:pass)
Всё остальноеОтклонено — ERR-PROXY-052

В режиме плейсхолдера агент контролирует, какое поле разрешается и куда оно направляется. Приведённое выше сопоставление применяется только к режиму совпадения URL.

Error codes

Каждый сбой генерирует стабильный код 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

Если вышестоящий 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.

Configuration

Секреты (ключ расшифровки учётных данных, ID агента, ID устройства, URL хранилища) находятся в зашифрованной конфигурации CLV1 sidecar, записанной один раз во время clavitor-proxy init. Операционные параметры находятся в переменных окружения:

ПеременнаяПо умолчаниюНазначение
CLAVITOR_PROXY_LISTEN127.0.0.1Интерфейс прослушивания. Установите 0.0.0.0 для общих развёртываний или конкретный IP-адрес интерфейса.
CLAVITOR_PROXY_PORT1983Порт прослушивания
CLAVITOR_PROXY_ALLOW_PRIVATEfalseРазрешить соединения с частными сетями (RFC 1918)
CLAVITOR_PROXY_MAX_BODY_MB64Ограничение размера тела запроса
CLAVITOR_PROXY_WRITE_TIMEOUT300Таймаут записи ответа в секундах
CLAVITOR_CONFIG(каталог исполняемого файла)Переопределить путь к конфигурации sidecar

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

Проведите собственный аудит.

Криптография представляет собой единый аудируемый артефакт WASM. Модель угроз задокументирована. Если вы найдёте что-то, что мы упустили, мы хотим услышать об этом.