OxL Справочник OxL
РусскийEnglish

13.2 Аутентификация

oxl
enum Principal {
  User(id: UserId, roles: Set<AppRole>, claims: Map<str, str>, mfa: bool, tenant: str?)
  Service(name: str, role: str)
  Node(id: NodeId)
  Anonymous
}
  • Провайдеры задаются в cluster { auth { … } }: jwt(issuer, audience?, jwks?), oidc(issuer, clientId), apikey, session(cookie: name). Роли пользователя: roles from claim("roles") as AppRole.

Определяется реализацией. OIDC (D-8055; DIV-025; D-4739). Необязательная возможность: провайдер oidc(issuer, clientId). Эта реализация его не содержит; проверка JWT по jwks или заданному ключу (jwt(…)) поддерживается.

  • apikey — ключ в заголовке (apikey(header: h), по умолчанию x-api-key) или в Authorization: ApiKey …; сервер хранит только хеш ключа, ключ даёт Principal.User. session(cookie: name) — серверная сессия: createSession(user, roles, ttl) -> str | SessionError (std.rpc) создаёт сессию и возвращает идентификатор, который клиент несёт в cookie name; endSession(id) её завершает; установка Set-Cookie — дело приложения. Порядок: Bearer (jwt) → ключ → cookie сессии; первый предъявленный решает; предъявленный неверный документ — UNAUTHENTICATED, отсутствие всех — Anonymous. Заголовки учётных данных не попадают в ctx.meta и не передаются дальше (D-8065; D-8200..D-8202, D-8208).

Определяется реализацией. Хранилище ключей и сессий (D-8065; DIV-025; D-8200, D-8201). Эта реализация: ключи — JSON-файл с SHA-256 (OXL_AUTH_APIKEYS / --auth-apikeys; поля id, sha256, sub, roles, tenant, mfa, claims, expires), сравнение за постоянное время, перечитывается при изменении; нет файла — все ключи отвергаются; сессия — запись {exp, principal} под хешем идентификатора в реплицируемом хранилище, срок 1 мс..30 суток.

  • Проверка выполняется до входа в обработчик. Неудача — AccessDenied (UNAUTHENTICATED).
  • Сервисы и узлы опознаются по mTLS-сертификату.
  • Делегирование: исходящие вызовы из обработчика несут исходного пользователя (ctx.caller) и вызывающий сервис (ctx.via). Сузить права: asScoped(caller.scoped([…])) { … }; вызвать от имени своего сервиса: asService { … }. Вызовы внешних сервисов (S.connect(addr)) идентичность пользователя и сервиса НЕ несут: заголовки x-oxl-principal и x-oxl-user туда не передаются, а authorization входящего вызова не пересылается (приложение при необходимости кладёт собственный документ в ctx.meta) (D-8066; D-8300).

Определяется реализацией. Тип идентификатора пользователя (D-8056; DIV-049; D-2905). UserId в Principal.User и в userId() — тип приложения (например, distinct u64), а стандартная библиотека не знает его. Эта реализация хранит идентификатор в Principal.User как str (значение claim sub JWT); Ctx.userId() и isUser принимают и возвращают str; приложение разбирает его в свой UserId (в V.5 — функцией callerId(ctx)).

Методы Principal: isUser(id: UserId?) -> bool (ложь при none и не-пользователе), has(role: AppRole) -> bool, service(name: str) -> bool, userId() -> UserId | AccessDenied. В обработчиках ctx.userId() — сокращение для ctx.caller.userId(); в политиках принципал доступен как caller.

cluster-auth

См. также

Исходник: docs/spec/oxl-standard.md