Перейти к содержимому

Безопасность и эксплуатация NextPDF Connect

NextPDF Connect аутентифицирует сетевые транспорты с помощью bearer-токена API-ключа. Локальный транспорт Model Context Protocol (MCP) он рассматривает как доверенный подпроцесс. Каждый инструмент с высоким риском защищён явным подтверждением человеком. На этой странице описаны модель аутентификации, безопасность транспорта и модель угроз.

Окно терминала
composer require nextpdf/server

У сервера три границы доверия: по одной для каждого транспорта.

Транспорт MCP stdio — это подпроцесс, который запускает локальный клиент. Он читает JSON-RPC из стандартного ввода и пишет ответы в стандартный вывод. У этого транспорта нет сетевого слушателя и API-ключа. Он наследует доверие от границы процесса операционной системы — именно такую модель доверия спецификация MCP определяет для stdio. Журналирование направляется в стандартный поток ошибок, поэтому оно никогда не повреждает поток протокола.

Сетевыми являются транспорт REST и транспорт gRPC. Оба требуют bearer-токен API-ключа в каждом запросе, кроме неаутентифицированных проб работоспособности. Оба транспорта используют одно и то же хранилище ключей, формат ключа и проверку с постоянным временем. Транспорт gRPC читает токен из метаданных вызова. REST читает его из заголовка Authorization.

Некорректная аутентификация — это сбой, который OWASP Application Programming Interface (API) Security Top 10 относит к API2:2023 Broken Authentication. Дефекты в этой области мешают API надёжно идентифицировать вызывающую сторону и тем самым подрывают безопасность API в целом (OWASP API Security Top 10, API2:2023). Слабые или предсказуемые токены также указаны как антипаттерн нарушенной аутентификации (тот же источник, перечень уязвимостей). Описанная ниже конструкция учитывает оба риска.

Ключ имеет вид npk_live_{kid}_{secret}. Параметр kid — это восьмисимвольный идентификатор для поиска записи за O(1), а энтропию несёт секрет. Хранилище никогда не хранит ключ в открытом виде. Оно хранит SHA-256-дайджест полного материала ключа. При каждом запросе сервер хеширует предъявленный токен и сравнивает его с сохранённым дайджестом с постоянным временем (hash_equals), поэтому неверный ключ ничего не раскрывает через тайминг. Отключённый или просроченный ключ отклоняется после проверки хеша, а не до неё.

Валидаторы REST и gRPC используют общую логику. Промежуточное ПО REST читает Authorization: Bearer npk_live_…. Аутентификатор gRPC читает тот же bearer-токен из метаданных вызова gRPC authorization, которые передаются как заголовки HTTP/2. Он завершает вызов ошибкой со статусом gRPC UNAUTHENTICATED.

Оба транспорта также применяют антиавтоматизационное ограничение к доаутентификационному трафику: избыточные попытки от одного клиентского идентификатора ограничиваются по частоте и отклоняются — 429 Too Many Requests в REST и статусом gRPC RESOURCE_EXHAUSTED в gRPC. Этот механизм активен по умолчанию, поэтому защищает развёртывание, где хранилище ограничения частоты не настроено отдельно. Клиентам следует выдержать паузу, а не сразу повторять запрос.

Запрос REST с отсутствующим, некорректным, отключённым или просроченным ключом получает 401 Unauthorized с телом problem-details и заголовком ответа WWW-Authenticate: Bearer. Это соответствует требованию HTTP: ответ 401 ДОЛЖЕН содержать поле заголовка WWW-Authenticate хотя бы с одним вызовом (RFC 9110 §11.6.1). Это требование следует из правила, по которому запрос с пропущенными или недействительными учётными данными должен получить 401 и вызов WWW-Authenticate (RFC 9110 §11.6).

Каждая запись ключа задаёт максимальный продуктовый уровень. Конвейер REST прикрепляет к запросу идентичность и уровень аутентифицированного клиента, поэтому последующая авторизация может применять ограничения возможностей и размера полезной нагрузки по уровню. Ключ уровня core не может выполнить операцию Pro или Enterprise, даже если эти пакеты установлены.

  • У транспорта MCP нет API-ключа. Это сделано намеренно и корректно для локального подпроцесса. Не открывайте MCP-сервер через сетевую прослойку. Если инструменты нужны сетевому агенту, разместите его перед транспортом REST или gRPC, которые выполняют аутентификацию.

  • Пробы работоспособности анонимны намеренно. /healthz и /readyz обходят аутентификацию, чтобы оркестраторы могли проверять работоспособность и готовность без учётных данных. Они возвращают только статус. Они не раскрывают данные инструментов или документов.

  • Токен подтверждения одноразовый и кратковременный. Шлюз с участием человека (human-in-the-loop) выдаёт токен, привязанный к имени инструмента, со сроком жизни 300 секунд. Токен расходуется при первом использовании. Это не учётные данные для аутентификации, и он не заменяет API-ключ.

Аутентификация — это один хеш и одно сравнение с постоянным временем на каждый запрос. Эти затраты пренебрежимо малы по сравнению с затратами на отрисовку. Хранилище ключей с горячей перезагрузкой перечитывает файл ключей при его изменении, поэтому ротация не требует перезапуска и не добавляет затрат к запросу.

Каждый инструмент объявляет уровень риска. Инструменты наивысшего уровня, ApprovalRequired, не выполняются при первом вызове. Шлюз подтверждения возвращает вызов с одноразовым токеном. Агент должен показать вызов человеку и повторно вызвать инструмент с этим токеном. Это намеренный механизм контроля в точке, где автоматизированное действие создаёт риск. Именно такую точку IEC 31010 определяет для контроля риска, вносимого действием человека (здесь — агента), в момент его внесения или рядом с ним (IEC 31010:2019). Конфигурация не может ослабить шлюз: переопределение конфигурации может только повысить риск инструмента, но никогда не понижает инструмент уровня ApprovalRequired. См. /connect/hitl-risk-tiers/.

Сетевые транспорты сами не терминируют Transport Layer Security (TLS); TLS относится к зоне ответственности развёртывания. Эталонное комбинированное развёртывание запускает транспорт gRPC с взаимным TLS, где ключ, сертификат и клиентский CA предоставляются как секреты развёртывания. При взаимном TLS сервер предъявляет сертификат, а также требует и проверяет клиентский сертификат. Запускайте транспорт REST за TLS-терминатором (обратным прокси или сервисной сеткой) и никогда не выставляйте слушатель в открытом виде в недоверенную сеть. Подробности настройки приведены в /connect/deployment/. Это утверждение о готовности, а не гарантия “под ключ”: безопасный транспорт требует корректной настройки развёртывания.

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

Сервер хранит документы только в хранилище документов в памяти, в течение настроенного времени жизни (TTL) (по умолчанию 1800 секунд) и в ограниченном количестве (по умолчанию 50). Он не сохраняет содержимое документа на диск, если вы явно не вызовете инструмент вывода в файл и путь не пройдёт проверку ограничения. Сервер не делает исходящих сетевых вызовов для отрисовки или проверки документа, поэтому байты документа не покидают развёртывание, если только инструмент явно не настроен на получение удалённого ресурса. Для развёртываний без сохранения состояния, чувствительных к резидентности данных, отключите вывод в файл (allow_file_output: false) и ограничьте enabled_tools минимальным набором.

Безопасная телеметрия и очистка журналов

Заголовок раздела «Безопасная телеметрия и очистка журналов»

Аудиторское журналирование фиксирует выполнения инструментов с уровнем риска Caution и выше, а также каждый выданный вызов подтверждения. Аудиторская запись содержит имя инструмента, уровень риска и флаг успеха. Считайте аргументы инструментов потенциально чувствительными: направляйте журналы в приёмник с контролем доступа и не повышайте глобальный уровень журналирования до детализации, при которой полезная нагрузка аргументов отражается в общих средах. Транспорт MCP пишет журналы в стандартный поток ошибок, поэтому содержимое журналов никогда не попадает в поток протокола в стандартном выводе.

УтверждениеИсточникreference_id
Нарушенная аутентификация подрывает безопасность APIперечень OWASP API Security Top 10, API2:2023
Слабые/предсказуемые токены — это антипаттерн нарушенной аутентификацииперечень OWASP API Security Top 10, API2:2023
401 ДОЛЖЕН нести вызов WWW-Authenticate в заголовкеRFC 9110 §11.6.1
Пропущенные/недействительные учётные данные → 401 + вызовRFC 9110 §11.6
Контроль риска в точке его внесения (человеком)IEC 31010:2019

Модель доверия stdio в Model Context Protocol следует официальной спецификации MCP, ревизия 2025-06-18. Её URL указан на /transports/mcp/, поскольку спецификация MCP не входит в закрытый корпус стандартов.

Инструменты подписи, редактирования (redaction), соответствия и криминалистики доступны только тогда, когда nextpdf/premium установлен вместе с сервером. Их наличие не меняет модель аутентификации. Их уровень риска всё равно помещает деструктивные инструменты за шлюз с участием человека.

  • /connect/hitl-risk-tiers/ — модель риска и подробный конверт подтверждения
  • /connect/deployment/ — TLS, взаимный TLS, секреты и настройка воркеров
  • /transports/rest/ — конвейер промежуточного ПО REST и схема безопасности OpenAPI
  • /transports/grpc/ — аутентификация по метаданным gRPC и коды состояния
  • /connect/configuration/ — enabled_tools, выбор хранилища ключей, переопределения риска