Токены с привязкой к отправителю — Versola Docs
VersolaVersola/docs
До 1.00.7.1versola.kzGitHub

Токены с привязкой к отправителю

Как в Versola работают DPoP и access-токены, привязанные к сертификату mTLS, какие поля и ключи конфигурации ими управляют и как их проверяет edge.

Токен доступа с привязкой к отправителю связан с ключом или сертификатом, которым владеет клиент. Тот, кто скопировал такой токен, не сможет им воспользоваться без этого ключа или сертификата. Versola поддерживает два механизма: DPoP (RFC 9449) и токены, привязанные к сертификату mTLS (RFC 8705).

Чем опасны bearer-токены

Bearer-токен работает у любого, кто его предъявил. Если он утёк из лога, прокси, расширения браузера или отчёта о падении, владелец утечки может вызывать ваш API до истечения срока токена. Привязка к ключу меняет доказательство: вместо «у меня есть строка» нужно «у меня есть строка и закрытый ключ».

Тенанты с профилем безопасности fapi2 требуют от каждого клиента один из двух механизмов.

DPoP

В DPoP клиент владеет парой ключей и подписывает для каждого запроса короткий JWT-proof.

Что отправляет клиент:

ЗапросЗаголовки
Запрос токена в authDPoP: <proof>. Access-токен в ответе привязан к ключу proof как cnf.jkt
Вызов API через edgeAuthorization: DPoP <access_token> и DPoP: <proof>. В proof есть htm, htu и ath (хеш access-токена)

Как это проверяется:

  • Алгоритмы. По умолчанию ES256 и PS256. RS256 поддерживается, но в набор по умолчанию не входит. Ключи RSA — не короче 2048 бит.
  • htu. auth строит ожидаемый URL из настроенного issuer, а edge — из edge-url. Заголовок Host не используется. На listener с mTLS-алиасами htu должен совпадать с адресом алиаса.
  • Повтор. jti proof запоминается, повторное использование отклоняется.
  • Nonce. Если nonce обязателен, proof без свежего nonce получает ответ use_dpop_nonce с заголовком DPoP-Nonce. Клиент повторяет запрос, добавив nonce в proof. auth требует nonce на уровне тенанта (requireDpopNonce, по умолчанию false; Challenges & Security, DPoP). edge требует его, когда у записи в Edges включено Require DPoP nonce.
  • Где. auth проверяет proof на /token и /userinfo. edge проверяет его на проксируемых вызовах.

Ключи конфигурации:

ГдеКлючПо умолчаниюСмысл
authdpop.iat-leeway60sДопустимое расстояние между iat proof и текущим временем
authdpop.nonce-ttl300sСколько времени выданный nonce принимается
edgedpop.iat-leewayзадаётся в конфигурации edgeТо же на прокси
edgedpop.nonce-ttlзадаётся в конфигурации edgeТо же на прокси
edgedpop.nonce-saltзадаётся в конфигурации edgeСекрет для генерации nonce

Поля клиента (Central API, Clients в консоли):

ПолеСмысл
dpopBoundAccessTokensКлиент всегда использует DPoP. Запрос токена без proof отклоняется с invalid_dpop_proof
dpopSigningAlgsСужает алгоритмы proof для клиента. Пустой список ничего не сужает. Можно только убрать алгоритмы, которые сервер объявляет в dpop_signing_alg_values_supported
dpopMinRsaKeySizeМинимальная длина модуля RSA в битах. Значения меньше 2048 отклоняются при регистрации

Токены, привязанные к сертификату mTLS

В mTLS клиент аутентифицируется сертификатом X.509, а access-токен содержит SHA-256-отпечаток сертификата как cnf.x5t#S256. Introspection возвращает тот же claim.

  • Listener. auth дублирует /token, /introspect, /revoke, /par и /userinfo на отдельном TLS-listener на порту MPORT (по умолчанию 8083), который требует клиентский сертификат. Listener запускается, только если в конфигурации auth есть блок mutual-tls с certificate, private-key, trusted-certificates и external-url. У trusted-certificates нет значения по умолчанию: без него не доверялся бы ни один сертификат.
  • Discovery. Когда listener включён, discovery-документ получает mtls_endpoint_aliases с адресом из external-url. Для запросов с сертификатом клиент должен обращаться к этим алиасам.
  • mTLS на прокси. Если mTLS завершает обратный прокси, auth читает сертификат из заголовка. Настройка выполняется на уровне тенанта в Challenges & Security, Mutual TLS: mtlsCertificateHeader и mtlsCertificateEncoding (urlEncodedPem или base64Der). Оба поля задаются или очищаются вместе. Клиент с аутентификацией по сертификату на тенанте без этой настройки отклоняется.

Поля клиента:

ПолеСмысл
authMethodtls_client_auth (субъект сертификата сверяется с зарегистрированным значением) или self_signed_tls_client_auth (ключ сертификата сверяется с jwks клиента). Не меняется после создания
mtlsAuthДля tls_client_auth: subjectType (subject_dn, san_dns, san_uri, san_ip, san_email) и subjectValue
certificateBoundAccessTokensПривязывает токены к сертификату для клиента, который аутентифицируется иначе. Клиент с аутентификацией по сертификату всегда получает привязанные токены

Исключение: у нативного клиента за edge сертификат принадлежит edge и общий для всех установок, поэтому его токены привязаны только к ключу DPoP устройства, а certificateBoundAccessTokens должно быть false.

Как выбрать

СитуацияЧто использовать
Мобильное или десктопное приложениеDPoP. Ключ хранится в хранилище ключей устройства
Сервис вызывает ваш API с контролируемого вами бэкендаtls_client_auth с токенами, привязанными к сертификату, или private_key_jwt с DPoP
Браузерное приложение за edgeНа стороне клиента настраивать нечего. Токены остаются внутри edge, браузер работает с сессией в cookie EDGE_SESSION
Нельзя запустить listener с клиентскими сертификатами или проксиDPoP

Как с ними работает edge

edge решает по claim cnf токена, а не по схеме, которую выбрал вызывающий.

ТокенКак предъявленРезультат
cnf.jktAuthorization: DPoP с корректным proofПринят
cnf.jktAuthorization: BearerОтклонён (dpop_downgrade). Это действует даже без блока dpop в edge
cnf.x5t#S256cookie EDGE_SESSIONПринят. Сертификат принадлежит самому edge
cnf.x5t#S256заголовок AuthorizationОтклонён. edge не может проверить сертификат вызывающего
cnf.jkt и cnf.x5t#S256proof DPoPОтклонён. Корректного proof недостаточно, если вторую половину привязки (сертификат) показать нельзя
без cnfAuthorization: DPoPОтклонён. Proof ничего не говорит о непривязанном токене

Если убрать блок dpop из конфигурации edge, проверка DPoP отключается, но токены, привязанные к ключу, по Bearer всё равно отклоняются. Нативному приложению, работающему через edge, блок dpop обязателен.

См. также