Тема
Корпоративный вход (SSO)
DoQA поддерживает вход через корпоративный провайдер идентификации по протоколу OpenID Connect (OIDC). Настраивается один провайдер на инсталляцию: Keycloak, AD FS, Azure AD (Entra), Blitz, GitLab self-managed — любой OIDC-совместимый.
Параметры SSO_* не входят в поставляемый шаблон .env. Добавьте нужные строки в .env вручную. После правки .env перезапустите приложение: ./doqa stop && ./doqa start.
Регистрация клиента в провайдере
Перед правкой .env заведите DoQA как OIDC-клиент на стороне провайдера. Что нужно с обеих сторон:
- DoQA доступна по HTTPS на постоянном адресе.
- Провайдер доступен по сети из контейнера приложения: по его адресу идут чтение конфигурации, обмен кода на токен и загрузка ключей подписи.
- Провайдер отдаёт конфигурацию по
{issuer}/.well-known/openid-configurationи подписывает ID-токен алгоритмом RS256. Токен, подписанный другим алгоритмом, DoQA отклоняет.
Клиент должен быть confidential (с секретом) и работать по authorization code flow. Разрешите scope openid email profile и укажите адрес возврата:
https://<APP_URL>/api/auth/sso/callbackАдрес возврата сверяется символ в символ: протокол, домен, порт, путь и завершающий слеш должны совпадать со значением SSO_REDIRECT, иначе провайдер откажет во входе.
Адрес провайдера должен быть одним и тем же для браузера и для контейнера приложения. Частая ошибка в Docker: в SSO_ISSUER записан внутренний адрес вроде http://keycloak:8089, к которому у браузера пользователя нет доступа.
Памятки по распространённым провайдерам:
- Keycloak — Clients → Create → OpenID Connect; «Client authentication» = On, секрет на вкладке «Credentials»; в «Valid redirect URIs» — адрес возврата; issuer —
https://<keycloak>/realms/<realm>. - AD FS, Azure AD (Entra ID) — App registration; Redirect URI типа Web — адрес возврата; выпустите секрет клиента; включите выдачу ID-токена; настройте выдачу claims
emailиname. - GitLab self-managed — Admin/Group/User → Applications; Redirect URI — адрес возврата; scopes
openid email profile; issuer — базовый адрес GitLab, напримерhttps://gitlab.company.ru.
Включение
Добавьте в .env:
SSO_ENABLED=true
SSO_ISSUER=https://idp.company.ru/realms/company
SSO_CLIENT_ID=doqa
SSO_CLIENT_SECRET=<секрет клиента из IdP>
SSO_REDIRECT=https://doqa.company.ru/api/auth/sso/callback
SSO_SCOPES="openid email profile"
SSO_LABEL="Corporate SSO"| Параметр | Описание |
|---|---|
SSO_ENABLED | Включает корпоративный вход. По умолчанию false. Кнопка на странице входа появляется, только если заданы ещё и SSO_ISSUER, SSO_CLIENT_ID, SSO_CLIENT_SECRET. |
SSO_TYPE | Тип коннектора. По умолчанию oidc — других значений нет. |
SSO_ISSUER | Адрес провайдера. Конфигурация читается по стандартному пути {issuer}/.well-known/openid-configuration, отдельно указывать адреса authorize/token/jwks не нужно. С этим адресом сверяется значение iss в ID-токене. Синоним параметра — SSO_BASE_URL. |
SSO_CLIENT_ID | Идентификатор клиента, заведённого в провайдере. |
SSO_CLIENT_SECRET | Секрет клиента. Хранится только в .env. |
SSO_REDIRECT | Адрес возврата. Должен указывать на https://<APP_URL>/api/auth/sso/callback и быть добавлен в список разрешённых redirect URI на стороне провайдера. |
SSO_SCOPES | Запрашиваемые scope, через пробел или запятую. По умолчанию openid email profile. Scope openid обязателен: без него провайдер не вернёт ID-токен. |
SSO_LABEL | Название провайдера, которое видит пользователь на странице входа. По умолчанию Corporate SSO. |
На странице входа появляется кнопка «Корпоративный вход (SSO)». Форма логина и пароля остаётся на месте: пока не включён SSO_ENFORCE, оба способа входа работают одновременно.
Тонкая настройка
Эти параметры менять обычно не нужно.
| Параметр | Описание |
|---|---|
SSO_DISCOVERY_CACHE_TTL | Время кэширования конфигурации провайдера, секунды. По умолчанию 3600. |
SSO_JWKS_CACHE_TTL | Время кэширования ключей подписи (JWKS), секунды. По умолчанию 3600. Кэш нужен для ротации ключей на стороне провайдера. |
SSO_CLOCK_LEEWAY | Допустимое расхождение часов сервера и провайдера при проверке срока действия токена, секунды. По умолчанию 60. |
SSO_STATE_TTL | Время жизни одноразового state/nonce/PKCE, секунды. По умолчанию 600. Определяет, сколько у пользователя есть времени на аутентификацию в провайдере. |
Как сопоставляются учётные записи
Когда пользователь входит через провайдера, DoQA ищет для него учётную запись по такому порядку:
- Если внешняя учётная запись уже привязана, вход выполняется в связанного пользователя.
- Если email подтверждён провайдером и такой пользователь в DoQA есть, внешняя учётная запись привязывается к нему автоматически, дальше вход идёт по привязке. Неподтверждённый email для поиска не используется, иначе чужую учётную запись можно было бы захватить.
- Если пользователя нет, он создаётся, но только при включённом JIT-провижининге (ниже).
- Иначе во входе отказано.
Роли из провайдера не читаются и не синхронизируются: права в DoQA древовидные, по проектам и пространствам, их выдаёт администратор внутри продукта.
Автоматическое создание пользователей (JIT)
JIT-провижининг создаёт пользователя при первом входе. Без него в DoQA смогут войти только те, кого администратор завёл заранее.
SSO_JIT_ENABLED=true
SSO_JIT_MODE=domain_allowlist
SSO_JIT_ALLOWED_DOMAINS=company.ru| Параметр | Описание |
|---|---|
SSO_JIT_ENABLED | Включает автоматическое создание. По умолчанию false. |
SSO_JIT_MODE | domain_allowlist — создавать только пользователей с доменом email из списка SSO_JIT_ALLOWED_DOMAINS. open — создавать любого, кого пропустил провайдер. По умолчанию domain_allowlist. Отдельного значения «выключено» нет. За это отвечает SSO_JIT_ENABLED. |
SSO_JIT_ALLOWED_DOMAINS | Домены через запятую или пробел. Учитываются только при SSO_JIT_MODE=domain_allowlist. Пустой список означает, что не создаётся никто. |
Что происходит с созданным пользователем:
- Роль — «просмотр», всегда. Выбрать другую роль при создании нельзя.
- Место в лицензии он не занимает: редактором его делает администратор вручную, см. Лицензии (серверная версия).
- Локального пароля у него нет — только вход через провайдера.
- Права на проекты и пространства выдаёт администратор внутри DoQA.
Внимание
Если SSO_JIT_MODE указан с опечаткой (любое значение, кроме domain_allowlist и open), пользователи не создаются вообще, а во входе новым сотрудникам отказывается без внятной причины. При SSO_JIT_MODE=open учётную запись в DoQA получит каждый, кто может войти в ваш провайдер. Проверьте, что круг пользователей провайдера действительно совпадает с кругом сотрудников, которым нужен DoQA.
JIT-политика общая для SSO и LDAP: те же три параметра включают автоматическое создание при первом входе по LDAP.
Обязательный вход через SSO (enforce)
SSO_ENFORCE=true запрещает вход по локальному паролю тем, кто считается управляемым через SSO: домен email входит в SSO_JIT_ALLOWED_DOMAINS либо к учётной записи привязана внешняя. Форма логина и пароля на странице входа при этом скрывается.
Исключение — только явный список:
SSO_ENFORCE=true
SSO_BREAKGLASS_EMAILS=admin@company.ru| Параметр | Описание |
|---|---|
SSO_ENFORCE | Запрещает вход по паролю для SSO-управляемых пользователей. По умолчанию false. Проверка серверная. Вход по LDAP enforce не ограничивает: если включён LDAP_ENABLED, пароли по-прежнему проверяются в каталоге. |
SSO_BREAKGLASS_EMAILS | Email через запятую или пробел, которым вход по паролю остаётся разрешён при любых условиях. |
Заполните break-glass до включения enforce
Автоматических исключений нет. Владелец системы и суперадмин под SSO_ENFORCE попадают на общих основаниях.
Если включить SSO_ENFORCE=true с пустым SSO_BREAKGLASS_EMAILS, то при недоступном провайдере в DoQA не сможет войти никто: паролем вход запрещён, а через провайдера он не проходит. Восстановить доступ можно будет только правкой .env на сервере и перезапуском приложения.
Заполните SSO_BREAKGLASS_EMAILS до того, как включите SSO_ENFORCE, и проверьте, что у перечисленных учётных записей задан пароль.
Вход по паролю при недоступном провайдере
Форма пароля под SSO_ENFORCE скрыта, но не удалена. Чтобы её открыть, добавьте к адресу страницы входа параметр ?password:
https://<APP_URL>/auth/login?passwordВход по этой форме пройдёт только для email из SSO_BREAKGLASS_EMAILS. Остальным SSO-управляемым пользователям сервер откажет, даже если пароль верный. Пользователей, чей домен не в списке SSO_JIT_ALLOWED_DOMAINS и у кого нет привязанной внешней учётной записи, enforce не касается: они входят паролем как обычно.
Задать пароль пользователю break-glass можно из консоли сервера. Пароль будет запрошен скрытно:
bash
docker compose exec api php artisan users:set-password admin@company.ruПроверка настройки
- Откройте страницу входа. Если кнопки «Корпоративный вход (SSO)» нет,
SSO_ENABLEDне применился: проверьте, что приложение перезапущено после правки.env. - Нажмите кнопку. Браузер должен уйти на страницу аутентификации провайдера.
- После входа вас вернёт в DoQA. Если вместо этого страница входа показывает «Не удалось войти через внешнего провайдера», причина указана в адресной строке параметром
error=sso_*и в логах:
bash
docker compose logs -f apiЗначение error | Причина |
|---|---|
sso_callback | Провайдер вернул ошибку или не передал код авторизации. Проверьте SSO_REDIRECT в .env и список разрешённых redirect URI в провайдере. |
sso_state | Истекло время на аутентификацию (SSO_STATE_TTL) или запрос пришёл повторно. |
sso_not_allowed | Пользователя нет в DoQA, а JIT выключен либо домен email не входит в SSO_JIT_ALLOWED_DOMAINS. |