API / Auth / MCP Сложно

OAuth Protected Resource: куда агенту идти за токеном

Что такое OAuth Protected Resource Metadata (RFC 9728), зачем она агентам, минимальный пример, правильно vs неправильно, ошибки и как проверить.

Обновлено:

Что это

OAuth Protected Resource Metadata (RFC 9728) — JSON по адресу /.well-known/oauth-protected-resource, который у защищённого ресурса (вашего API) объявляет: какие authorization-серверы выдают для него токены, какие scopes нужны и как передавать токен. Это пара к OAuth Discovery: discovery описывает сервер авторизации, а этот документ — защищённый ресурс.

Зачем это AI-агентам

Агент стучится в ваш API и получает 401. Что дальше? Без метаданных он не знает, где взять токен. RFC 9728 даёт ответ: вот authorization_servers, иди туда. Связка discovery + protected-resource позволяет агенту пройти весь OAuth-флоу автономно. Именно эту схему использует современный MCP для авторизации.

Минимальный рабочий пример

GET /.well-known/oauth-protected-resource HTTP/1.1
{
  "resource": "https://api.example.com",
  "authorization_servers": ["https://example.com"],
  "scopes_supported": ["read", "write"],
  "bearer_methods_supported": ["header"]
}

Плюс на 401 ресурс указывает, где искать метаданные:

WWW-Authenticate: Bearer resource_metadata="https://api.example.com/.well-known/oauth-protected-resource"

Правильно vs неправильно

ПравильноНеправильно
resource = канонический URL APIНесовпадение с реальным адресом
authorization_servers ведут на валидный RFC 8414-серверСсылка на сервер без discovery
401 + WWW-Authenticate с resource_metadata401 без подсказки, где метаданные
Абсолютные HTTPS-URLОтносительные/HTTP

Типичные ошибки

  • authorization_servers указывает на сервер без OAuth Discovery — цепочка рвётся.
  • Нет WWW-Authenticate с resource_metadata на 401 — агент не найдёт вход.
  • resource ≠ фактический URL — клиент отвергнет токен (audience mismatch).
  • Заявлены scopes, которых сервер не выдаёт.

Как проверить

Скан проверит наличие и валидность. Вручную:

curl -s https://api.example.com/.well-known/oauth-protected-resource | jq .
curl -sI https://api.example.com/ | grep -i www-authenticate

Ждём валидный JSON с resource и authorization_servers.

Источники