edge при старте читает один HOCON-файл. На странице перечислены его ключи, указано, какой секрет стоит за каждым и откуда он берётся, и описано, из-за чего edge отказывается запускаться. О правилах загрузки, переменных окружения и блоках, общих с auth и central, см. Справочник по конфигурации.
versola configure и Helm-чарт генерируют этот файл для разворачиваемого релиза, поэтому вручную его пишут редко. В цели vps ручная правка пропадает при следующем configure.
Загрузка и переменные окружения
Путь к файлу берётся из CONFIG_PATH (в образе по умолчанию /app/config/env.conf). Вместо файла весь HOCON можно передать в ENV_CONFIG. Ключи пишутся в kebab-case, длительности — в формате HOCON ("60 seconds", 5 minutes), подстановка ${VAR} работает.
| Переменная | По умолчанию | Значение |
|---|---|---|
PORT | 8080 | Порт приложения |
DPORT | 8081 | Порт диагностики: /metrics, /liveness, /readiness |
BIND_HOST | 0.0.0.0 | Адрес привязки |
CONFIG_PATH | /app/config/env.conf | Путь к HOCON-файлу |
RUN_MIGRATIONS | false | true применяет миграции при старте. Иначе edge только проверяет схему и останавливается, если она устарела |
WARMUP_ENABLED, WARMUP_BUDGET_SECONDS | true, 20 | Прогрев до готовности |
POSTGRES_POOL_METRICS_INTERVAL | нет | Переопределяет postgres.pool-metrics-interval |
edge не читает APORT и MPORT.
Ключи
«Обязательный» означает, что у ключа нет значения по умолчанию и без него edge не запустится.
Верхний уровень
| Ключ | Обязательный | По умолчанию | Значение |
|---|---|---|---|
env | да | Имя окружения. prod включает проверки для продакшена, и тогда /service/configuration/sync отвечает 404 | |
id | да | ID этого edge. Должен совпадать с edge, зарегистрированным в central (Edges в консоли). Генерируется edge-default | |
key-id | да | kid ключа ниже. Попадает в заголовок токена, который edge подписывает для central | |
private-key | да | Закрытый ключ RSA, PKCS#8, base64. Им edge подписывает синхронизирующие вызовы в central (RS256). Открытая часть хранится в central | |
configuration-cache-refresh-interval | да | Как часто edge перечитывает из central ресурсы, эндпоинты, разрешения, роли, клиентов, пресеты, JWKS и политику DPoP. Генерируется 5 minutes для vps и Kubernetes, 1 minute локально | |
versola-url | да | Публичный URL auth. Сюда перенаправляется браузер, с ним сравнивается iss токена | |
versola-internal-url | нет | versola-url | URL, по которому сам edge обращается к auth. Отличается от versola-url, если edge и браузер ходят к auth по разным сетям |
versola-internal-trusted-certificates | нет | пусто | Закрепления для сертификата HTTPS-эндпоинта, к которому edge обращается, когда клиент аутентифицируется сертификатом, а versola-internal-url — https (TLS-терминатор перед auth). Если не задано, такие вызовы отклоняются. Если versola-internal-url — обычный HTTP и есть блок native, такие вызовы идут на native.auth-mutual-tls-url и проверяются по native.trusted-certificates. См. Закреплённые сертификаты |
edge-url | да | Публичный origin, по которому клиенты обращаются к edge. htu proof DPoP строится из него, а не из заголовка Host | |
central.url | да | Базовый URL Central API | |
otel-exporter | нет | нет | Конечная точка OTLP gRPC для трассировки. Если не задан, трассировка выключена |
security
| Ключ | Обязательный | Значение |
|---|---|---|
token-encryption.key | да | 32 байта, base64url. Ключ AES для refresh-токенов в таблице сессий edge. Если его потерять или сменить, все сохранённые сессии перестанут обновляться |
edge-sessions.secret | да | 32 байта, base64url. Должен быть задан, но в этом релизе не читается |
edge-sessions.ttl | да | Длительность. Должна быть задана, но в этом релизе не читается. Срок cookie определяется refresh-токеном. Генерируется 30 days |
internal-secret | нет | Base64url. Пароль для POST /service/configuration/sync вне продакшена, пользователь edge. Если не задан, эндпоинт недоступен |
postgres
Тот же блок, что в auth и central: см. Справочник по конфигурации. Для edge нужна своя база или своя схема в общей базе (цели CLI используют общую базу с ...?currentSchema=edge). edge слушает отзывы на отдельном соединении, поэтому за пулером в transaction-режиме задайте notifications-url. Генерируемые значения для edge: maximum-pool-size = 10, minimum-idle = 10.
cleanup
Удаляет просроченные строки. Для edge генерируется, max-threads = 2:
| Таблица | Размер пакета | Интервал | Ключевой столбец |
|---|---|---|---|
pending_logins | 1000 | 5 minutes | state |
edge_sessions | 500 | 1 hour | ctid |
revocations | 1000 | 1 hour | revoked_key |
revocation
Необязательный блок. Значения ниже заданы в коде.
| Ключ | По умолчанию | Значение |
|---|---|---|
reload-interval | 600 seconds | Как часто список отзывов в памяти сверяется с базой, с разбросом. Обычно отзывы приходят уведомлением, так что это страховка |
purge-interval | 60 seconds | Как часто удаляются записи об истёкших токенах |
overlap | 30 seconds | На сколько сверка отступает назад от последней прочитанной позиции, чтобы подхватить строки, закоммиченные с опозданием |
batch-size | 50000 | Строк за одно чтение |
dpop
Необязательный блок. Без него edge отклоняет запросы со схемой DPoP, но токен, привязанный к ключу, через Bearer всё равно отклоняется. Блоку native он обязателен. Допустимые алгоритмы берутся из метаданных сервера в central, а требование nonce задаётся настройкой Require DPoP nonce у этого edge в разделе Edges. Здесь ни то ни другое не настраивается.
| Ключ | Обязателен в блоке | Значение |
|---|---|---|
nonce-salt | да | 32 байта, base64url. Ключ собственного пространства DPoP-Nonce у edge. Не общий с auth: nonce от auth в edge недействителен |
iat-leeway | да | Максимальное расстояние iat proof от текущего времени в обе стороны. Задаёт и размер защиты от повторов. Генерируется 60 seconds |
nonce-ttl | да | Сколько выданный nonce остаётся действительным. Генерируется 600 seconds |
native
Необязательный блок. Если его нет, любой вызов /native/* отвечает 404. Описание потока — в разделе Нативные приложения.
| Ключ | Обязательный | По умолчанию | Значение |
|---|---|---|---|
auth-mutual-tls-url | да | Адрес, по которому edge обращается к mutual-TLS-слушателю auth (MPORT) | |
auth-mutual-tls-external-url | нет | auth-mutual-tls-url | Как auth называет этот слушатель (его mutual-tls.external-url). Из него строится htu proof устройства для /token и /revoke |
trusted-certificates | да | Список путей к PEM: конечные сертификаты, которые может предъявить слушатель. Минимум один | |
blob-key | да | 32 байта, base64url. Ключ AES-256-GCM, которым запечатывается blob из /native/start. Отдельный ключ, не token-encryption.key | |
blob-ttl | нет | 600 seconds | Сколько blob можно предъявить. Дополнительно ограничен временем жизни pushed-запроса в auth |
auth-issuer | нет | versola-url | iss в ответах авторизации auth (его jwt.issuer). Задайте, если он отличается от versola-url, иначе /native/complete отклонит ответ |
Секреты и откуда они берутся
В цели vps и в локальной цели versola configure генерирует каждый секрет, сохраняет его в OpenBao по пути secret/versola/<target>/edge и передаёт в окружение контейнера как ${VAR}, на которую ссылается HOCON-файл. В Kubernetes те же ключи приходят из Secret (Kubernetes). См. Секреты.
| Переменная | Ключ конфигурации | Формат | Примечания |
|---|---|---|---|
EDGE_PRIVATE_KEY | private-key | RSA PKCS#8 | Хранится вместе с EDGE_KEY_ID. Открытая часть, EDGE_PUBLIC_JWK, уходит в central. Новая пара в работающей системе приводит к 401 на всех вызовах edge в central |
EDGE_KEY_ID | key-id | текст | Должен совпадать с kid ключа, зарегистрированного в central |
EDGE_TOKEN_ENC_KEY | security.token-encryption.key | 32 байта | Генерируется только при первой установке. Отсутствие значения при обновлении — ошибка, а не тихая перегенерация |
EDGE_SESSIONS_SECRET | security.edge-sessions.secret | 32 байта | |
EDGE_INTERNAL_SECRET | security.internal-secret | любая длина | |
EDGE_DPOP_NONCE_SALT | dpop.nonce-salt | 32 байта | |
EDGE_NATIVE_BLOB_KEY | native.blob-key | 32 байта | |
POSTGRES_PASSWORD | postgres.password | текст |
Секрет в 32 байта — это URL-safe base64 ровно от 32 байт. Другая длина останавливает запуск.
Проверки при старте
edge отказывается запускаться и называет ключ, если:
- не задан обязательный ключ, у секрета неверная длина или
private-keyне является ключом RSA в формате PKCS#8; - путь в
versola-internal-trusted-certificatesилиnative.trusted-certificatesне содержит сертификата либо содержит удостоверяющий центр. Проверяется каждый сертификат в каждом файле, проходят только конечные сертификаты; native.trusted-certificatesпуст;- блок
nativeесть, а блокаdpopнет; - значение
trusted-certificates— просто строка. Нужен список; - схема базы устарела, а
RUN_MIGRATIONSне равенtrue; env = "prod", а URL Postgres не на loopback не проверяет TLS;- он не может прочитать список отзывов из базы. Реплика без списка принимала бы отозванные токены, поэтому она остаётся вне обслуживания.
Минимальный пример с комментариями
Это файл в стиле vps; необязательные блоки опущены, кроме dpop. Секреты — подстановки, которые берутся из окружения.
env = prod
id = "edge-default" # тот же ID, что у edge в central
key-id = ${EDGE_KEY_ID}
private-key = ${EDGE_PRIVATE_KEY} # PKCS#8 RSA, base64
configuration-cache-refresh-interval = "5 minutes"
versola-url = "https://id.example.com" # что видят браузеры и что сверяется с iss токена
edge-url = "https://id.example.com" # из этого строится htu для DPoP
central { url = "http://127.0.0.1:8090" }
security {
token-encryption { key = ${EDGE_TOKEN_ENC_KEY} }
edge-sessions {
secret = ${EDGE_SESSIONS_SECRET}
ttl = 30 days
}
}
postgres {
url = "jdbc:postgresql://db.example.com:5432/versola?currentSchema=edge"
user = "versola"
password = ${POSTGRES_PASSWORD}
maximum-pool-size = 10
minimum-idle = 10
connection-timeout = "30 seconds"
max-lifetime = "30 minutes"
leak-detection-threshold = "60 seconds"
}
cleanup {
max-threads = 2
tables = [
{ table-name = "pending_logins", batch-size = 1000, interval = "5 minutes", key-column = "state" }
{ table-name = "edge_sessions", batch-size = 500, interval = "1 hour", key-column = "ctid" }
{ table-name = "revocations", batch-size = 1000, interval = "1 hour", key-column = "revoked_key" }
]
}
dpop {
nonce-salt = ${EDGE_DPOP_NONCE_SALT}
iat-leeway = "60 seconds"
nonce-ttl = "600 seconds"
}
Блок native добавляйте, только если обслуживаете нативные приложения:
native {
auth-mutual-tls-url = "https://id.example.com:8083"
trusted-certificates = ["/certs/auth-mtls.crt"]
blob-key = ${EDGE_NATIVE_BLOB_KEY}
}
Закреплённые сертификаты
versola-internal-trusted-certificates и native.trusted-certificates — списки путей к PEM-файлам. Каждый элемент закрепляет конкретный конечный сертификат, это не якорь доверия. HTTP-клиент edge не проверяет имя хоста, поэтому доверие к УЦ принимало бы любой сертификат, который этот УЦ когда-либо выпустил, для любого хоста. Поэтому УЦ отклоняется при старте.
native {
trusted-certificates = ["/certs/auth-mtls-old.crt", "/certs/auth-mtls-new.crt"]
}
versola-internal-trusted-certificates = ["/certs/auth-internal.crt"]
Принимается серверный сертификат, совпавший с любым элементом списка. Чтобы сменить сертификат слушателя auth без простоя:
- Положите старый и новый конечные сертификаты в список на каждом
edgeи перезапустите их. - Переключите
authна новый сертификат и перезапустите его. - Когда у каждого
edgeновый список, удалите старый элемент.
edge читает файлы при старте, поэтому после замены файла нужен перезапуск. Старая форма trusted-certificates = "/path" больше не разбирается: оберните значение в [...].
Что дальше
- Клиентские сертификаты edge: как
edgeполучает сертификат, который предъявляетauth. - Секреты: где лежат сгенерированные значения.
- Kubernetes: те же ключи в Helm-чарте.