Возможности
В комплекте всё. Большая часть выключена.
FoxAuth — это один сервер без редакций. Authorization Code с PKCE и OpenID Connect работают с первого запуска, а почти всё остальное ждёт за именованным флагом. На практике ваша поверхность атаки — это ровно те возможности, которые вы сами запросили. На каждой карточке указано, включена ли возможность сразу или ждёт своего флага.
Каждый флаг ниже ведёт на свою запись в справочнике настроек: он генерируется из кода и называет значение по умолчанию и последствия.
Протокол
Любой тип гранта, который может запросить клиент OAuth 2.1.
Гранты и эндпоинты. Authorization Code с PKCE и OpenID Connect включены всегда; большая часть остального ждёт флага.
Authorization Code с PKCE
PKCE обязателен для каждого клиента, публичного или конфиденциального, как того требует OAuth 2.1. Redirect URI сравниваются точно.
OpenID Connect Core 1.0
ID-токены, эндпоинт UserInfo и discovery — со стандартным набором claims и попарными (pairwise) идентификаторами субъекта.
Идентификация издателя
Каждый ответ авторизации содержит iss, поэтому клиента нельзя обманом заставить принять код другого издателя.
Resource Indicators
Ограничьте аудиторию токена параметром resource и проверяйте её на сервере ресурсов. Включено по умолчанию.
Грант Client Credentials
Токены для взаимодействия между машинами, без конечного пользователя, со scope, заданными для каждого клиента.
Грант Refresh Token
Долгие сессии с ротацией и обнаружением повторного использования. Предъявите токен повторно — и отзывается всё выданное разрешение. Включено по умолчанию: этот тип гранта доступен, пока offline_access входит в поддерживаемые scope.
Device Authorization Grant
Вход на телевизоре или в CLI: пользователь вводит код на другом устройстве.
CIBA
Аутентификация по обратному каналу, инициированная клиентом: клиент запрашивает, пользователь подтверждает по отдельному каналу.
Pushed Authorization Requests
Клиент сначала отправляет запрос напрямую серверу, а через браузер передаёт только request_uri.
Объекты запроса
Подписанные параметры request и request_uri: целостность самого запроса авторизации защищена.
JARM
Ответы авторизации, защищённые JWT: подписанные и, при необходимости, зашифрованные.
Rich Authorization Requests
Детальные authorization_details вместо строки scope — для платежей и похожих сценариев.
Интроспекция токенов
Серверы ресурсов спрашивают у издателя, активен ли ещё токен и что он содержит.
Ответы интроспекции в виде JWT
Подписанные ответы интроспекции — для сервера ресурсов, которому нужно доказать, что именно ему сообщили.
Отзыв токенов
Клиент отзывает токен доступа или refresh-токен, который ему больше не нужен.
Подписанные ответы UserInfo
UserInfo возвращается в виде подписанного JWT вместо обычного JSON.
Параметр claims
Выбор claims в каждом запросе, включая обязательные (essential) claims и запрос acr.
Выход по инициативе RP
Завершение сессии со стороны клиента, с шагом подтверждения, чтобы ссылка не могла незаметно выполнить выход пользователя. Включено по умолчанию.
Backchannel logout
Уведомление всех клиентов сессии о её завершении — напрямую, от сервера к серверу.
Безопасность
Привязка к отправителю и защита, которая уже включена.
Профили банковского уровня — это флаги, а не редакции. Всё остальное в этом списке включено с первого запуска.
DPoP
Токены доступа и refresh-токены, привязанные к отправителю, включая серверные nonce: одного украденного токена недостаточно.
Аутентификация клиента по mTLS
Клиентские сертификаты для аутентификации и токены доступа, привязанные к сертификату.
Поведение профилей FAPI
Более строгие проверки, которых требуют профили Financial-grade API, — одним переключателем.
Шифрование токенов и ответов
Зашифрованные ID-токены, ответы UserInfo и JARM на зарегистрированных ключах клиента.
Второй фактор TOTP
Одноразовые пароли на основе времени в каждом бакете; для консоли администратора их можно сделать обязательными.
Попарные идентификаторы субъекта
Свой sub для каждого сектора, с солью из базы данных, поэтому две доверяющие стороны не могут сопоставить пользователя.
Троттлинг перебора паролей при входе
Сохраняемые счётчики неудачных попыток для каждой учётной записи с нарастающими блокировками. Отказ из-за троттлинга выглядит точно так же, как неверный пароль.
Ограничение частоты запросов по origin
Свои лимиты для каждого класса маршрутов, включено по умолчанию; число доверенных прокси-хопов настраивается.
CORS, закрытый данными
Origin получает доступ к ответам, только если его указал проект, которому принадлежит вызывающий клиент. Никакая настройка с wildcard его не открывает.
Заголовки безопасности
HSTS, Permissions-Policy, защита от встраивания во фреймы и от подмены типа содержимого — в каждом ответе.
Контроль доступа по scope
Проверка scope для каждого клиента — на эндпоинте авторизации и ещё раз на эндпоинте токенов.

Администрирование
Один API управления, три входа.
Консоль, HTTP API и инструменты MCP обращаются к одним и тем же маршрутам, поэтому проверки и запись аудита не могут разойтись.
Консоль администратора
Проекты, OAuth-клиенты, администраторы и их группы, бакеты пользователей, конечные пользователи, внешние провайдеры, подключения SCIM, настройки, SMTP и ключи подписи. У каждого экрана есть свой адрес. Изменение, которое может закрыть людям вход или сломать приложения, сначала сообщает, кого оно затронет и сколько их, и применяется только после вашего подтверждения.
Журнал аудита только на дозапись
Каждое действие администратора, меняющее состояние, фиксирует исполнителя, действие, объект и время. Запись делается до изменения, а у хранилища нет способа обновить или удалить её.
Активные пользователи бакета за месяц
Каждый бакет считает людей, которым выдал токены, — по одному разу за месяц и за день по UTC, отдельно для локального входа, входа через внешнего провайдера, продления и поставки из каталога. Закрытый месяц больше не меняется, а история переживает и самих людей, и бакет. Страница Usage показывает каждый бакет рядом с группой-владельцем, поэтому экземпляр, который вы держите для других команд или клиентов, может сказать, кто сколько использовал.
Администрирование через MCP
126 инструментов MCP: ИИ-агент вызывает их по POST /mcp, защищённому ресурсу OAuth 2.1, а операции с серьёзными последствиями требуют подтверждения вторым вызовом.
Авторизация для ваших собственных MCP-серверов
Объявите сторонний MCP-сервер защищённым ресурсом проекта, и этот сервер будет выпускать токены, аудитория которых — ровно этот ресурс, без изменений в коде и без перезапуска. В бакете с собственным адресом объявлению ничего не нужно от самого ресурса — он может быть внутренним, работать на localhost или ещё не быть развёрнутым, — а другой тенант может объявить тот же URL, никак не затронув ваш. По умолчанию токены самодостаточны, поэтому ресурс проверяет их по опубликованным ключам своего бакета, не имея собственных учётных данных.
Документы идентификации клиента
client_id — это HTTPS-URL JSON-документа с описанием клиента; документ загружается и проверяется по требованию и никогда не сохраняется. Именно этот механизм спецификация авторизации MCP называет первым для клиента, с которым у сервера нет предварительных отношений.
Динамическая регистрация клиентов
Клиенты регистрируются сами в рамках политики регистрации. Спецификация MCP объявила этот механизм устаревшим в пользу документов идентификации клиента.
Управление регистрацией
Чтение, изменение и удаление регистрации с помощью её registration access token.
Клиенты в базе данных
Клиенты хранятся в собственном хранилище сервера и создаются через консоль, API, динамическую регистрацию или скрипт настройки. Статического файла с клиентами нет.
Владение через группы
Проекты и бакеты пользователей принадлежат группе. Доступ даёт только членство в ней, и оно проверяется заново при каждом запросе. Бакет переходит к другой группе вместе с проектами, которые им пользуются.
Бакет по пути или по хосту
Каждый бакет пользователей — отдельный издатель со своими метаданными и ключами подписи, доступный по пути на сервере или по собственному имени хоста: одно из двух, но не оба сразу. Имя хоста позволяет браузеру изолировать cookie входа этого бакета по origin и публикует одно расположение метаданных вместо двух; цена — DNS-запись и сертификат, которые вы предоставляете сами. Смена адреса — отдельная операция: она показывает, какие клиенты сломаются, ещё до того, как их сломать.
Удаление бакета можно отменить
Удаление сразу отключает бакет, а уничтожает его через 30 дней. До этого срока в нём ничего не уничтожается, и восстановление возвращает бакет со всеми сессиями и refresh-токенами, которые продолжают действовать.
Самообслуживание конечных пользователей
Подтверждение email и сброс пароля в каждом бакете — с лимитами попыток, паузами между ними и одноразовыми ссылками.
Управление конечными пользователями
Пригласите человека, чтобы он сам задал себе пароль, отметьте адрес как подтверждённый или завершите вход человека в одно приложение, не трогая остальные. До 100 человек можно разом деактивировать, активировать, удалить или завершить их сессии, и у каждого будет своя запись в журнале аудита.
Вход через Google, Microsoft, Apple или GitHub
Подключите провайдера по имени, и консоль покажет, что сделать на его стороне и какой именно адрес callback зарегистрировать; вы вводите только выданные им значения. Любого другого провайдера OIDC можно настроить вручную. Настройка делается для каждого бакета пользователей, поэтому у каждого тенанта своё приложение. Пробный вход показывает, что сделает настоящий вход, ещё до того, как на провайдера кто-то положится, а callback отклоняет ответ, если его прислал не тот издатель, у которого начался вход. Администраторы тоже могут входить в консоль через провайдера вашей организации.
Поставка пользователей по SCIM 2.0
Microsoft Entra ID, Okta или любой каталог с SCIM 2.0 создаёт, изменяет и удаляет пользователей и группы бакета. Удаление сразу многих людей можно не применять, а задержать до проверки. Заменённый секрет или статический токен продолжает работать, пока каталог не перейдёт на новый.
Управление ключами подписи
Каждый бакет с собственным адресом подписывает своими ключами, опубликованными по его собственному jwks_uri, поэтому токен одного тенанта никогда не пройдёт проверку на сервере ресурсов другого. Группа — владелец бакета ротирует их одним действием: новый ключ публикуется до того, как им можно подписывать, а выведенный из оборота остаётся опубликованным, пока не истекут его токены. Скомпрометированный ключ можно сразу отозвать, и ничто подписанное им больше не пройдёт проверку. Набор ключей экземпляра при этом остаётся за суперадминистратором.

Расширяемость
Меняйте поведение без форка.
Именованные точки расширения и единый интерфейс адаптера, поэтому ваши изменения должны пережить обновление.
31 точка переопределения
Поиск учётной записи, политика взаимодействия, ротация refresh-токенов, разрешение ресурсов, попарные идентификаторы, обработка RAR и многое другое — всё подменяется в момент вызова.
Подключаемое хранилище
Каждая сохраняемая модель проходит через единый интерфейс адаптера. В комплекте реализации: PostgreSQL, MongoDB и хранилище в памяти; какую использовать, определяет одна строка подключения.
Монтируемое приложение Elysia
Импортируйте приложение и смонтируйте его в своём сервисе на Bun. Шага инициализации нет — сервер запускается при импорте.
Встроенный интерфейс входа и согласия
Экраны на React и Ant Design, которые можно оформить под себя или заменить через политику взаимодействия.
Эксплуатация
То, что нужно, когда что-то пошло не так.
Разверните, наблюдайте и выясняйте, почему запрос завершился ошибкой.
Готовый образ контейнера
ghcr.io/redfox-soft/oauth-server-ts с тегом для каждого релиза и latest, а также Compose-файл, который подготавливает схему.
Хранилище ошибок сервера
Внутренние сбои записываются и доступны для просмотра в консоли. Обычные отказы клиентам — это корректное поведение, и туда они не попадают.
Отправка в Sentry по желанию
Отправка отчётов полностью вынесена из обработки запроса: сбой попадает в неё только после того, как классифицирован как дефект, поэтому ответы не меняются.
Понятные настройки
Для каждой настройки уровня сервера описаны тип, значение по умолчанию и последствия, а редактируется она в консоли.
Машиночитаемый справочник
Справочники эндпоинтов, настроек, Admin API, инструментов MCP и переменных окружения генерируются из самого кода.
Дальше
Сравните с тем, что используете сейчас.
Мы ведём фактическое датированное сравнение с серверами, с которыми FoxAuth обычно сопоставляют.
Уже используете другое решение? Мы ведём датированные сравнения с Auth0, authentik, Keycloak, Ory Hydra и Zitadel, и в каждом указано, какие страницы мы прочитали и когда.