edge — плоскость трафика Versola: обратный прокси, который выполняет вход пользователей, хранит их сессии, проверяет каждый запрос к вашему API по разрешениям и правилам из central и только потом пересылает его дальше. Ещё он даёт нативным мобильным приложениям отдельный канал к auth. Начните с этой страницы, если хотите поставить Versola перед API. Нужна работающая установка хотя бы с одним тенантом (Запуск Versola локально).
Когда нужен edge
edge нужен, когда решение о доступе должно приниматься один раз перед API, а не повторяться в каждом сервисе:
- Браузерное приложение без токенов в JavaScript.
edgeвыступает OAuth-клиентом. Браузер получает только cookieEDGE_SESSION(HttpOnly,Secure,SameSite=Strict). - Политики вне кода. Разрешения, CEL-правила по эндпоинтам, step-up-аутентификация и подстановка идентичности настраиваются в консоли администратора, а не пишутся в сервисе.
- Нативное приложение в профиле безопасности
fapi2. У приложения нет учётных данных клиента. См. Нативные приложения. - Вызовы между сервисами. Токен
client_credentialsпроверяется по разрешениям клиента тем же конвейером.
edge не нужен, если ваши сервисы уже сами проверяют токены auth и шлюз вам не требуется. auth работает и без него.
Три способа аутентифицировать вызов
edge ищет учётные данные в таком порядке и берёт первые найденные:
| Порядок | Учётные данные | Типичный вызывающий |
|---|---|---|
| 1 | Authorization: Bearer <access token> | Сервис или скрипт с непривязанным токеном |
| 2 | Authorization: DPoP <access token> и заголовок DPoP с proof | Нативное приложение или любой клиент с токеном, привязанным к ключу |
| 3 | Cookie 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. Пресеты создаются в консоли, в карточке клиента.
- Ваше приложение переводит браузер на
GET /login/{presetId}.edgeсохраняет PKCE-верификатор иstateэтого входа (живут 10 минут) и отвечает303на/authorizeвauth. Параметрыacr_values,max_age,prompt,login_hintиui_localesпередаются дальше. Остальные игнорируются. - Пользователь входит в
auth, и тот перенаправляет его наGET /completeвedgeсcodeиstate. edgeобменивает код, сохраняет зашифрованный refresh token в своей схеме, выставляетEDGE_SESSIONи отвечает303на URI после входа из пресета. Еслиauthвернул ошибку,edgeперенаправляет на тот же URI, добавивerror,error_descriptionиerror_uri.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.
Порты и служебные эндпоинты
| Порт | Переменная | По умолчанию | Что отдаёт |
|---|---|---|---|
| Приложение | PORT | 8080 | Всё, что описано на этой странице |
| Диагностика | DPORT | 8081 | GET /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в общей базе в простейшей конфигурации (цели CLIlocalиvps). В нём лежат сессии, незавершённые входы, отзывы и записи для защиты DPoP от повторов, и через него реплики согласуют работу. - Отзыв распространяется через Postgres
LISTEN/NOTIFY. Отозванный токен отклоняется по списку в памяти, который каждая реплика поддерживает актуальным.LISTENне работает через пулер в transaction-режиме: задайтеpostgres.notifications-urlс прямым URL (за пулером соединений). Сверка раз вrevocation.reload-interval(по умолчанию600 s) страхует от пропущенного уведомления. Реплика, которая не смогла загрузить список при старте, не запускается. - Конфигурация отстаёт. Ресурсы, эндпоинты, разрешения, клиенты и пресеты кэшируются и перечитываются каждые
configuration-cache-refresh-interval. Удалённое разрешение доходит до каждой реплики не позднее чем через один интервал. Отзыв токена этого интервала не ждёт. - Для нативных приложений нужен блок
native, а ему нуженdpop. Без них любой вызов/native/*отвечает404.
Что дальше
- Политики эндпоинтов: CEL-правила, step-up и подстановка по эндпоинтам.
- Конфигурация edge: все ключи и секреты.
- Как защитить API с помощью edge: рабочая настройка от начала до конца.
- Спецификации OpenAPI:
edge.yamlс описанием маршрутов.