API VEGA

mcp-server-auth-template

Читать на португальском

Ориентированный на продакшн справочник по OAuth 2.1 resource server для удалённого MCP: Microsoft Entra ID и универсальный OIDC, точная валидация токенов/ресурсов, отказоустойчивая авторизация, прогрессивные scope challenges, stateless MCP 2026-07-28 и доказательства OpenTelemetry только на основе метаданных.

Используйте этот репозиторий, когда сложность не в том, «как мне предоставить доступ к инструменту MCP?», а в том, как сделать это, не ослабляя границы идентификации, авторизации, транспорта и наблюдаемости. Сервер работает в паре с mcp-client-auth-template как исполняемый сквозной справочник, использующий синтетические идентификаторы и никаких продакшн-учётных данных.

Что доказывает этот репозиторий

Парный исполняемый путь проверяет реальное поведение resource server, а не заявления о конфигурации:

  • ✅ Метаданные защищённого ресурса RFC 9728 публикуются resource server
  • ✅ Привязка ресурса RFC 8707 становится точной границей аудитории JWT
  • ✅ issuer, подпись, срок действия, совместимость алгоритма/ключа и тип вызывающей стороны работают по принципу fail closed
  • ✅ делегированные scopes и роли приложения Entra остаются разными концепциями авторизации
  • 403 insufficient_scope возвращается до диспетчеризации для прогрессивной авторизации
  • ✅ токены с неправильной аудиторией отклоняются с 401
  • ✅ защищённые инструменты остаются скрытыми от анонимного обнаружения каталога
  • ✅ MCP 2026-07-28 остаётся stateless и не создаёт Mcp-Session-Id
  • ✅ универсальный OIDC и Microsoft Entra ID используют одну границу приложения без утечки данных провайдера
  • ✅ контекст трассировки W3C достигает сервера, в то время как чувствительные значения OAuth/MCP не попадают в телеметрию
  • ✅ релизные артефакты, доказательства контейнеров, SBOM и provenance проверяются исполняемыми gates

Для постатейного обзора парного поведения OAuth/MCP, включая явные пробелы в доказательствах и темы для обсуждения в MCP Authorization Interest Group / Tool Scopes Working Group, см. Отчёт о реализации авторизации.

Архитектура

flowchart LR
    Client["MCP client"] -->|"OAuth 2.1 / OIDC"| AS["Authorization server<br/>Entra ID or generic OIDC"]
    Client -->|"MCP 2026-07-28<br/>resource-bound bearer"| Admission["Transport admission"]
    Admission --> AuthN["Token verification"]
    AuthN --> AuthZ["Tool authorization"]
    AuthZ --> Tools["MCP tools"]
    Server["This resource server"] --- Admission

    Server -->|"OIDC discovery + cached JWKS"| AS
    Server -.->|"W3C trace context + OTLP"| Collector["OpenTelemetry Collector"]
    Collector --> Tempo["Tempo"]
    Tempo --> Grafana["Grafana"]

Сервер авторизации отвечает за вход, согласие, регистрацию клиента и выдачу токенов. Этот репозиторий отвечает за защищённый ресурс: допуск на транспортном уровне, публикацию метаданных, проверку access-токена, построение principal в рамках запроса, авторизацию инструментов и диспетчеризацию.

Границы слоёв и подробную последовательность авторизации см. в Архитектура.

5-минутная проверка

Сопутствующий клиент владеет исполняемым межрепозиторным эталонным сценарием. Если оба репозитория клонированы как соседние, проверьте этот сервер напрямую из исходников:

cd ../mcp-client-auth-template
./scripts/run_reference_demo.sh \
  --server-root ../mcp-server-auth-template

Сценарий запускает реальный сервер из этого checkout, а также детерминированный локальный OIDC-провайдер и доказывает CIMD-first Authorization Code + PKCE, аутентифицированный whoami, ограниченное повышение scope, отклонение токенов с неправильной аудиторией и stateless-поведение MCP.

Для доказательства на основе опубликованного образа с наблюдаемостью:

cd ../mcp-client-auth-template
./scripts/run_observability_demo.sh --keep

Сценарий с наблюдаемостью проверяет одну распределённую трассировку между клиентом и сервером, успешный приём Collector, извлечение из Tempo, провижининг Grafana и утверждения о приватности телеметрии.

См. Руководство по проверке для точного определения границ доказательств.

Визуальное доказательство

Терминальное доказательство ниже получено из парного эталонного сценария уровня исходного кода:

Скриншоты трассировки получены из успешного запуска с наблюдаемостью и сосредоточены на спанах mcp-server-auth-template:

Профили аутентификации

ПрофильПредполагаемое использованиеКлючевое поведение
Entra delegatedИнтерактивные корпоративные пользователиПроверяет scp, идентификаторы tenant/application, issuer, audience и subject
Entra applicationРазвёртывания только для приложений, специфичные для провайдераТребует явный idtyp=app; сохраняет roles отдельно от делегированных scopes
Generic OIDC delegatedИнтерактивные клиенты на основе стандартовПроверяет issuer/audience/подпись/срок действия и OAuth scopes
Generic OIDC client credentialsНеобслуживаемые сервисы в детерминированном парном профилеПринимает предварительно зарегистрированные машинные токены и прогрессивные OAuth scopes

Установите MCP_SERVER_AUTH_PROVIDER=entra или generic для переключения адаптеров. Пример инструмента whoami возвращает проверенную идентичность вызывающей стороны; health требует дополнительный scope mcp:tools:health и демонстрирует pre-dispatch 403 insufficient_scope challenge.

Быстрый старт

Предварительные требования: Python 3.13 или 3.14 и uv.

git clone https://github.com/brunovicco/mcp-server-auth-template.git
cd mcp-server-auth-template
cp .env.example .env
uv sync --frozen --all-groups
uv run uvicorn mcp_server_auth_template.entrypoints.mcp_server:create_app --factory --reload

Настройте блок Entra или generic-OIDC в .env, затем направьте MCP-клиент на http://localhost:8000/mcp.

EndpointНазначениеАутентификация
/mcpMCP Streamable HTTPBearer token
/.well-known/oauth-protected-resourceМетаданные обнаружения сервера авторизацииПубличный
/livezПроверка жизнеспособности процессаПубличный, минимальный ответ
/readyzГотовность жизненного цикла MCPПубличный, минимальный ответ

Для продакшн-подобного выполнения:

uv run python -m mcp_server_auth_template.entrypoints.serve

См. Продакшн-эксплуатация перед тем, как открывать сервис за пределами loopback.

Готовность к Official MCP Registry

P2.1 подготавливает этот репозиторий для пространства имён Official MCP Registry io.github.brunovicco/mcp-server-auth-template. server.json описывает публичный образ GHCR как OCI-пакет, использующий реальный транспорт streamable-http; он не заявляет хостируемый endpoint remotes. Версия 0.6.1 зарезервирована как первая неизменяемая версия образа, несущая требуемую метку владения io.modelcontextprotocol.server.name.

Публикация в Registry намеренно отделена от этого изменения готовности и происходит только после того, как защищённый релизный конвейер проверит финальный OCI index. См. Официальный реестр MCP.

Свойства безопасности

Реализация намеренно работает по принципу fail closed:

  • точная проверка issuer и audience, ограниченные проверки часов, совместимость алгоритма/ключа и обновление кэшированного JWKS;
  • усиленный исходящий трафик discovery/JWKS против небезопасных схем, перенаправлений, сжатия, тел чрезмерного размера, частных/зарезервированных назначений, смешанных DNS-ответов и DNS rebinding;
  • допуск по Host, Origin, заголовкам, envelope, размеру тела и параллелизму перед аутентификацией и диспетчеризацией инструментов;
  • делегированные и прикладные идентичности остаются разными; согласование расширений никогда не предоставляет авторизацию само по себе;
  • bearer-токены и декодированные claims остаются локальными для запроса и никогда не логируются и не сохраняются;
  • трассировка исключает учётные данные, произвольные заголовки и URL, аргументы/результаты MCP, тела, baggage и текст исключений.

Это прозрачная эталонная реализация, а не сертификация безопасности. Прочитайте Приватность и обработка данных и архитектурные решения в docs/adr/ перед адаптацией границ.

MCP 2026-07-28

Парные шаблоны проверяют современный stateless-профиль как исполняемое поведение:

  • server/discover и _meta каждого запроса передают версию протокола, идентификацию клиента и его возможности — без устаревшего рукопожатия initialize / initialized;
  • современные запросы используют MCP-Protocol-Version, Mcp-Method и Mcp-Name;
  • ответы не выпускают Mcp-Session-Id;
  • обнаружение сервера авторизации выполняется через Protected Resource Metadata;
  • параметр resource по RFC 8707 точно связывает аудиторию токена доступа;
  • runtime-ошибка 403 insufficient_scope сохраняет ранее выданные разрешения и допускает только один ограниченный повтор невыполненной операции;
  • доступ machine-to-machine включается только явно — через io.modelcontextprotocol/oauth-client-credentials.

См. Совместимость и межрепозиторные доказательства E2E сопутствующего клиента.

Наблюдаемость

Библиотека a2a-otel-kit продолжает контекст трассировки W3C на границе ASGI-слоя MCP. Экспорт телеметрии не выполняет никаких сетевых обращений, пока не настроены A2A_OTEL_ENABLED=true и полный OTLP-эндпоинт для трейсов. Спаны содержат только метаданные и создаются внутри усиленного слоя HTTP-приёма, но вне аутентификации и диспетчеризации инструментов.

См. Наблюдаемость LLM и приложения.

Инженерные доказательства

  • детерминированный quality gate, охватывающий линтинг, форматирование, строгую проверку Mypy, архитектуру, тесты и покрытие, Bandit, аудит зависимостей, контроль цепочки поставок, governance и валидацию вендоризированных контрактов;
  • GitHub Actions, зафиксированные по SHA, с правами только на чтение по умолчанию и изолированными полномочиями на выпуск релизов;
  • инвентаризации CycloneDX для исходного кода и рантайма, полная доказательная база по уязвимостям и политика исключений по принципу fail-closed;
  • побайтово воспроизводимые артефакты релизов Python из разрешённого списка с манифестами SHA-256 и build provenance от GitHub;
  • публикация в GHCR по утверждённой политике с неизменяемым дайджестом и аттестациями provenance и SBOM;
  • Python 3.13/3.14 с MCP SDK 2.0.0 и последней совместимой версией 2.x;
  • офлайн-фикстуры JWT на локальных ключах и синтетических идентичностях;
  • ADR, документирующие решения по безопасности, протоколу, эксплуатации, совместимости, наблюдаемости и цепочке поставок.

Демо и продакшен

Референсные доказательстваВнедрение в продакшене
Синтетический локальный OIDC в сопутствующем демоКорпоративный сервер авторизации с проверенной регистрацией и получением согласия
Loopback/локальная референсная сетьСетевое взаимодействие сервисов под защитой TLS и явная ответственность за прокси
Локальные Collector/Tempo/GrafanaУправляемый организацией пайплайн телеметрии и политика хранения
Синтетические ключи подписи и идентичностиУправляемые ключи, секреты и специфичные для провайдера механизмы контроля
Референсные инструменты whoami / healthДоменные инструменты с явными политиками авторизации и контролем побочных эффектов

Референсные настройки подтверждают работоспособность границ; это не значения по умолчанию для продакшена.

Структура репозитория

src/                    resource-server implementation
tests/                  unit, contract and security evidence
scripts/                quality, governance and release automation
docs/                   architecture, operations, privacy and security
examples/                deployment/reference configuration
.github/workflows/      CI, compatibility and release workflows

Состояние локальных редакторов и coding-агентов намеренно исключено из публичного репозитория.

Документация

ДокументДля чего использовать
ВерификацияПарные доказательства на уровне исходного кода и в наблюдаемом поведении
АрхитектураКонтекст, слои, правила зависимостей и последовательность обработки запросов
СовместимостьПоддерживаемые версии и исполняемый контракт клиент/сервер
ЭксплуатацияPreflight, пробы, завершение работы, контейнеры и Kubernetes
ПриватностьИнвентаризация данных, хранение, логирование, трассировка и внешние обработчики
Цепочка поставокПолитика зависимостей, граница доверия CI, угрозы и исключения
НаблюдаемостьКонфигурация OpenTelemetry и опционального Langfuse
РазработкаЛокальное окружение, проверки и контейнерный workflow
Архитектурные решенияОбоснование и компромиссы ключевых решений

Тестирование и качество

uv lock --check
uv sync --frozen --all-groups
uv run pytest
uv run python scripts/quality_gate.py

Quality gate — это определение готовности (definition of done). Он охватывает линтинг, форматирование, архитектуру, строгую типизацию, тесты и покрытие, Bandit, аудит зависимостей, контроль цепочки поставок, governance и валидацию вендоризированных контрактов.

Границы применимости и внедрение в продакшене

Этот репозиторий — референсный шаблон, а не хостинговый сервис идентификации. Конкретное развёртывание по-прежнему должно самостоятельно обеспечить терминацию TLS, публикацию неизменяемых образов, доставку секретов, регистрацию у провайдера, сетевые политики, планирование ёмкости, ответственных за мониторинг и проверку на живом IdP.

Закоммиченные значения .invalid и значения из одних нулей — это плейсхолдеры, которые не проходят production preflight.

Лицензия

MIT