Обзор edge — Versola Docs
VersolaVersola/docs
До 1.00.7.1versola.kzGitHub

Обзор edge

Что делает edge перед вашим API, какие учётные данные он принимает, как запрос проходит через него, какие порты слушает и чего не умеет.

edge — плоскость трафика Versola: обратный прокси, который выполняет вход пользователей, хранит их сессии, проверяет каждый запрос к вашему API по разрешениям и правилам из central и только потом пересылает его дальше. Ещё он даёт нативным мобильным приложениям отдельный канал к auth. Начните с этой страницы, если хотите поставить Versola перед API. Нужна работающая установка хотя бы с одним тенантом (Запуск Versola локально).

Когда нужен edge

edge нужен, когда решение о доступе должно приниматься один раз перед API, а не повторяться в каждом сервисе:

  • Браузерное приложение без токенов в JavaScript. edge выступает OAuth-клиентом. Браузер получает только cookie EDGE_SESSION (HttpOnly, Secure, SameSite=Strict).
  • Политики вне кода. Разрешения, CEL-правила по эндпоинтам, step-up-аутентификация и подстановка идентичности настраиваются в консоли администратора, а не пишутся в сервисе.
  • Нативное приложение в профиле безопасности fapi2. У приложения нет учётных данных клиента. См. Нативные приложения.
  • Вызовы между сервисами. Токен client_credentials проверяется по разрешениям клиента тем же конвейером.

edge не нужен, если ваши сервисы уже сами проверяют токены auth и шлюз вам не требуется. auth работает и без него.

Три способа аутентифицировать вызов

edge ищет учётные данные в таком порядке и берёт первые найденные:

ПорядокУчётные данныеТипичный вызывающий
1Authorization: Bearer <access token>Сервис или скрипт с непривязанным токеном
2Authorization: DPoP <access token> и заголовок DPoP с proofНативное приложение или любой клиент с токеном, привязанным к ключу
3Cookie EDGE_SESSION, которую /complete выставляет после входа в браузереБраузерное приложение

Что нужно доказать, определяет claim cnf токена, а не схема, которую выбрал вызывающий. Правила описаны в разделе Токены с привязкой к отправителю:

  • Токен, привязанный к ключу (cnf.jkt), через Bearer отклоняется, независимо от того, есть ли в конфигурации блок dpop.
  • Токен, привязанный к сертификату (cnf.x5t#S256), принимается только из cookie, потому что сертификат принадлежит самому edge.
  • Токен, привязанный и к ключу, и к сертификату, отклоняется при любом способе предъявления, включая cookie.
  • Заголовок DPoP с токеном, у которого нет привязки к ключу, отклоняется.

Если в cookie лежит просроченный access token, edge обновляет его по сохранённому refresh token и отправляет новую cookie. Токен из заголовка никогда не обновляется.

Жизненный цикл запроса

Вход в браузере через пресет

Пресет авторизации — именованный шаблон входа в клиенте: redirect URI, URI после входа и после выхода, scope, тип ответа, домен и путь cookie. Пресеты создаются в консоли, в карточке клиента.

  1. Ваше приложение переводит браузер на GET /login/{presetId}. edge сохраняет PKCE-верификатор и state этого входа (живут 10 минут) и отвечает 303 на /authorize в auth. Параметры acr_values, max_age, prompt, login_hint и ui_locales передаются дальше. Остальные игнорируются.
  2. Пользователь входит в auth, и тот перенаправляет его на GET /complete в edge с code и state.
  3. edge обменивает код, сохраняет зашифрованный refresh token в своей схеме, выставляет EDGE_SESSION и отвечает 303 на URI после входа из пресета. Если auth вернул ошибку, edge перенаправляет на тот же URI, добавив error, error_description и error_uri.
  4. GET /logout/{presetId} отправляет браузер на /logout в auth. Затем auth вызывает /logout/frontchannel и /logout/backchannel, и edge сбрасывает сессию.

Значение cookie — <presetId>:<accessToken>. Срок её жизни равен сроку refresh token, а если refresh token не выдавался, сроку access token.

Вызов API

Приложение вызывает /resources/{resourceId}/{path} методами GET, POST, PUT, PATCH или DELETE. Остальные методы не маршрутизируются. Дальше edge выполняет фиксированный конвейер: токен, отзыв, привязка, поиск ресурса и эндпоинта, разрешение, audience, необязательный userinfo, правило allow, step-up, подстановка, пересылка. Любой шаг может завершить запрос. Шаги, контекст CEL и коды ошибок описаны на странице Политики эндпоинтов.

Правила пересылки:

Часть запросаЧто получает ресурс
AuthorizationВнутренний ресурс: Basic, где имя пользователя — ID ресурса, а пароль — секрет ресурса в base64url. Токен вызывающего не пересылается. Публичный ресурс: токен вызывающего как Bearer
CookieВсе cookie, кроме EDGE_SESSION
Host, DPoP, Content-LengthУдаляются
Правила injectЗначения заголовков, query и полей JSON-тела верхнего уровня, вычисленные в CEL. Они заменяют то, что прислал клиент
ОтветСтатус и тело как у ресурса, без Set-Cookie. edge читает ответ целиком, прежде чем отдать его

Чтобы скрыть элементы интерфейса, можно запросить GET /permissions/me?resource=<id> (параметр можно повторять для нескольких ресурсов). Ответ — ID эндпоинтов, которые разрешены ролям вызывающего. Прокси применяет те же правила независимо.

Чего edge не делает

  • Не терминирует TLS. На PORT он отдаёт обычный HTTP, поставьте перед ним прокси с TLS. Для cookie с флагом Secure нужен HTTPS.
  • Не ограничивает частоту запросов, не кэширует, не переписывает пути и не фильтрует содержимое.
  • Не стримит ответы. Большой ответ ресурса сначала целиком буферизуется в памяти.
  • CEL-правила видят токен, claims из userinfo, параметры пути, query, заголовки и JSON-тело. Обратиться из правила к другому сервису нельзя.
  • Подстановка в тело работает только для JSON-объекта верхнего уровня, а все подставляемые значения — строки.
  • Не выдаёт токены и не хранит данные пользователей. Это делает auth.

Порты и служебные эндпоинты

ПортПеременнаяПо умолчаниюЧто отдаёт
ПриложениеPORT8080Всё, что описано на этой странице
ДиагностикаDPORT8081GET /liveness, GET /readiness, GET /metrics

edge не использует APORT и MPORT. В развёртывании vps, созданном через CLI, edge слушает 8095 и 8096. POST /service/configuration/sync заставляет edge сразу перечитать конфигурацию из central. Он нужен для тестов, требует Basic-учётные данные на основе security.internal-secret и отвечает 404, когда env равен prod. См. Конфигурация edge и Наблюдаемость.

Ограничения

  • Один Postgres для всех реплик. Все реплики edge используют один Postgres: собственную базу edge или схему edge в общей базе в простейшей конфигурации (цели CLI local и vps). В нём лежат сессии, незавершённые входы, отзывы и записи для защиты DPoP от повторов, и через него реплики согласуют работу.
  • Отзыв распространяется через Postgres LISTEN/NOTIFY. Отозванный токен отклоняется по списку в памяти, который каждая реплика поддерживает актуальным. LISTEN не работает через пулер в transaction-режиме: задайте postgres.notifications-url с прямым URL (за пулером соединений). Сверка раз в revocation.reload-interval (по умолчанию 600 s) страхует от пропущенного уведомления. Реплика, которая не смогла загрузить список при старте, не запускается.
  • Конфигурация отстаёт. Ресурсы, эндпоинты, разрешения, клиенты и пресеты кэшируются и перечитываются каждые configuration-cache-refresh-interval. Удалённое разрешение доходит до каждой реплики не позднее чем через один интервал. Отзыв токена этого интервала не ждёт.
  • Для нативных приложений нужен блок native, а ему нужен dpop. Без них любой вызов /native/* отвечает 404.

Что дальше