SSD Nodes Learn 🎉 VPS от $5.50/мес
Руководства Matt ConnorАвтор: Matt Connor

Почему SSO в self-hosted ПО часто платный

Разбираем феномен налога на SSO в open source проектах. Узнайте, почему поддержка OIDC и SAML выносится в платные тарифы и на что обратить внимание при выборе self-hosted систем.

Что такое «налог на SSO»

«Налог на SSO» в self-hosted программном обеспечении — это модель, при которой само приложение бесплатно, но за функцию единого входа (SSO) приходится платить. Вы можете развернуть всю систему на собственном VPS без лицензионных ключей и ограничений по количеству пользователей. Однако при попытке настроить аутентификацию в документации выясняется, что поддержка OpenID Connect (OIDC) или SAML (security assertion markup language) доступна только в платной версии.

Это важнее, чем обычная платная функция, так как именно SSO превращает набор разрозненных self-hosted сервисов в единую систему. Identity provider (IdP) обеспечивает наличие одной учетной записи для каждого пользователя, единую политику паролей, централизованное включение многофакторной аутентификации (MFA) и возможность мгновенной блокировки доступа. Без этого каждое приложение хранит собственную базу пользователей, которой приходится управлять вручную.

Эта практика существует достаточно давно, чтобы у неё появился публичный рейтинг. «Стена позора SSO» (SSO Wall of Shame) на сайте sso.tax содержит список вендоров, которые требуют значительную доплату за единый вход; записи в нём ведутся с 2018 года. Автор проекта устанавливает справедливый критерий: «Если поддержка SSO увеличивает стоимость на 10%, вы не попадете в этот список». Большая часть этого списка — проприетарное ПО. Теперь такая же логика ценообразования встречается и в проектах с открытым исходным кодом, которые вы размещаете на своих мощностях.

Почему разработчики переносят единый вход (SSO) в платные тарифы

Существуют две причины, и обе они объективны. Поддержка SSO обходится дорого, и это одна из немногих функций, за которую готовы платить крупные организации.

Затраты на поддержку реальны, так как интеграция с поставщиками идентификации (IdP) никогда не бывает завершенной. Каждый IdP форматирует свои утверждения (claims) немного по-своему. Сопоставление групп, время жизни сессии, URL-адреса перенаправления и расхождение системных часов — всё это порождает ошибки при входе в систему. Ошибка входа блокирует доступ сразу для всех пользователей, поэтому такие тикеты имеют наивысший приоритет. Затем следуют дополнительные запросы: вложенные группы, сопоставление ролей, автоматическая подготовка учетных записей через SCIM (system for cross-domain identity management) и журналы аудита, которые потребуются отделу комплаенса.

Финансовая сторона вопроса — это арифметика, а не злой умысел. Компания, которая не может подключить приложение к собственному IdP, не будет его внедрять вовсе. Таким образом, SSO проводит четкую границу между пользователем, который платит, и тем, кто этого не делает. Проекту с открытым ядром необходимо где-то провести эту черту. SSO подходит для этого лучше, чем почти любая другая функция, поэтому так много проектов выбирают именно её.

Одно уточнение к типичным жалобам: проверяйте changelog, прежде чем предполагать, что функция была удалена, так как удаление всегда отражается в release notes. В проектах, которые я изучил для этой статьи, платные функции SSO изначально создавались для платных тарифов. Я не нашел ни одного случая, когда работающая бесплатная функция SSO была бы отозвана. Grafana — типичный пример. На странице SAML есть примечание: "Available in Grafana Enterprise and Grafana Cloud", в то время как стандартный OAuth с вашим собственным провайдером работает в open source версии.

Во что на самом деле обходится «налог на SSO»

Деньги — это меньшая часть проблемы. Платные тарифы продаются из расчета на одного пользователя, поэтому счет растет вместе с вашей командой, в то время как хостинг и обновления остаются вашей задачей.

Большая часть затрат — это ручное управление учетными данными, и оно создает проблемы в четырех областях.

  • Отдельное хранилище паролей для каждого приложения: повторное использование одного пароля создает уязвимость во всех приложениях, где он применяется.
  • Удаление доступа по памяти. Вы должны помнить каждый сервис, к которому имел доступ сотрудник, и именно тот, который вы забудете, окажется критически важным.
  • Настройка MFA для каждого приложения отдельно, если приложение вообще поддерживает такую функцию.
  • Общие учетные записи, к которым прибегают небольшие команды под таким давлением.

Последний пункт заслуживает отдельного упоминания. Когда команда использует одну учетную запись администратора в системе управления документами, журнал аудита фиксирует одно имя для всех действий, поэтому невозможно определить, кто именно удалил счет. Права доступа для конкретных пользователей также перестают работать, так как существует только один пользователь. В этом и заключается реальный ущерб от «налога на SSO»: он подталкивает небольшие команды к использованию одной общей учетной записи, что хуже любого из альтернативных вариантов.

Чек-лист перед внедрением любого решения

Выполните эти действия до docker compose up, а не после того, как в приложении накопится 400 документов.

  1. Откройте страницу аутентификации в документации и прочитайте примечание о тарифных планах в начале раздела. Платные функции помечены специальным значком или отдельной строкой о доступности.
  2. Убедитесь, что приложение поддерживает OIDC или SAML для работы с вашим собственным провайдером, а не только с фиксированным списком публичных сервисов.
  3. Проверьте возможности сопоставления ролей и групп. Создание пользователя — это лишь половина дела; ручное назначение прав в десяти разных приложениях — это та часть, которая создает проблемы.
  4. Проверьте, принимает ли приложение имя аутентифицированного пользователя из заголовка доверенного прокси-сервера и можно ли ограничить список доверенных прокси.
  5. Изучите историю лицензий в git и проверьте, подписывают ли участники проекта CLA (соглашение о передаче прав на код).
  6. Проверьте процедуру увольнения сотрудника (offboarding). Выясните, что происходит с API (application programming interface) токенами и активными сессиями, когда учетная запись в IdP деактивируется.

Пункт 2 — это то, где чаще всего наступает разочарование. Кнопка "Sign in with Google" — это не OIDC с вашим провайдером идентификации, а фиксированная интеграция с конкретным вендором. Настоящая поддержка требует указания URL провайдера (issuer URL), а все остальные параметры определяются автоматически через discovery. Вы можете проверить сторону вашего провайдера одной командой.

curl -s https://id.example.com/.well-known/openid-configuration \
  | jq '.issuer, .authorization_endpoint, .token_endpoint'

От исправно работающего провайдера должны прийти три URL. Пустой результат или ошибка 404 обычно означают, что путь discovery указан неверно; этот путь зависит от конкретного провайдера: Keycloak публикует его по адресу /realms/<realm>/.well-known/openid-configuration. Если в приложении вообще нет поля для ввода issuer URL, оно не сможет работать с вашим IdP, что бы ни было написано в списке функций.

Пункт 6 часто обнаруживает проблемы спустя недели после увольнения сотрудника. Отключение учетной записи в IdP блокирует новые входы в систему. Это не отзывает API-токен, который приложение выдало ранее, так как приложение проверяет этот токен самостоятельно и не обращается к IdP для его валидации. Таким образом, процедура увольнения состоит из двух этапов: отключение учетной записи в IdP, а затем удаление пользователя или его токенов внутри каждого приложения.

Что на самом деле означают значки уровней

Данные сверены с документацией каждого проекта в августе 2026 года. Начнем с платных версий.

Grafana указывает SAML как «доступно в Grafana Enterprise и Grafana Cloud» наряду с синхронизацией команд и SCIM-провижинингом. Generic OAuth, GitHub OAuth, LDAP (протокол облегченного доступа к каталогам) и auth proxy входят в open source сборку, поэтому владелец небольшого self-hosted сервера может авторизоваться через своего провайдера. Платная граница проходит именно по SAML, а не по SSO в целом — это нюанс, который часто игнорируется при использовании термина «SSO tax».

Metabase формулирует это более прямо. В документации сказано: «SAML-аутентификация доступна только в планах Pro и Enterprise (как для self-hosted, так и для Metabase Cloud)». В open source версии остаются вход по паролю и LDAP.

Passbolt помечает свою документацию по SSO как Pro и Cloud, поэтому в community edition эта функция отсутствует. В документации указаны такие провайдеры, как Keycloak и Entra ID.

Теперь рассмотрим другую сторону, так как эта модель далеко не универсальна.

  • GitLab Self-Managed указывает «Tier: Free, Premium, Ultimate» на странице SAML, поэтому использование SAML с вашим собственным GitLab ничего не стоит.
  • Paperless-ngx настраивает OIDC через django-allauth с помощью PAPERLESS_SOCIALACCOUNT_PROVIDERS, скрывает форму локального входа через PAPERLESS_DISABLE_REGULAR_LOGIN и сопоставляет утверждения (claims) с группами через PAPERLESS_SOCIAL_ACCOUNT_SYNC_GROUPS.
  • Planka принимает OIDC_ISSUER, OIDC_CLIENT_ID и OIDC_CLIENT_SECRET, использует openid profile email в качестве scopes по умолчанию и назначает администраторов на основе роли из claims через OIDC_ADMIN_ROLES.
  • BookStack переключается через AUTH_METHOD=oidc, а затем сопоставляет группы провайдера со своими ролями через OIDC_USER_TO_GROUPS=true и OIDC_GROUPS_CLAIM.
  • Vaultwarden добавил «поддержку SSO через OpenID Connect» в версии 1.35.0 от 27 декабря 2025 года на основе pull request от участника, который ранее поддерживал эту функцию в форке.
  • listmonk поддерживает OIDC-авторизацию вместе с пользовательскими ролями начиная с версии v4.0.0.

Используйте эту информацию при выборе, а не после того, как вы уже внедрили решение. Kanban-доска Planka и другие self-hosted альтернативы Trello обрабатывают идентификацию по-разному, как и BookStack, Wiki.js и Outline. Бесплатный OIDC — это функция, которую можно оценивать наравне с лимитами хранилища или наличием мобильных клиентов. Если вы только составляете список, что развернуть самостоятельно в 2026 году станет хорошей отправной точкой, а система управления документами Paperless-ngx и Vaultwarden уже сегодня предоставляют бесплатный OIDC.

Почему обратный прокси перед приложением — это не единый вход (SSO)

Распространенный обходной путь — это forward auth. Ваш обратный прокси задерживает каждый запрос, запрашивает у службы аутентификации, вошел ли этот браузер в систему, и только после этого передает запрос приложению. authentik называет это прокси-провайдером (proxy provider), имеющим режим forward auth для одного приложения и другой — для всего домена. Authelia и oauth2-proxy выполняют ту же задачу.

Блок сайта Caddy выглядит следующим образом, согласно собственному примеру authentik.

app.example.com {
  forward_auth http://authentik-outpost:9000 {
    uri /outpost.goauthentik.io/auth/caddy
    copy_headers X-Authentik-Username X-Authentik-Email X-Authentik-Groups
    trusted_proxies private_ranges
  }
  reverse_proxy app:8000
}

Регистр имен этих заголовков важен в Caddy, так как несовпадающее имя придет пустым. При каждом одобренном запросе outpost устанавливает X-authentik-username, X-authentik-email, X-authentik-groups и некоторые другие.

Вот что вы получаете в результате. Никто не попадет в приложение, не пройдя сначала через вашего провайдера идентификации (IdP), поэтому неисправленная форма входа больше не доступна из интернета, а MFA применяется ко всему, что находится за прокси, одновременно.

Вот чего вы не получаете: идентификации внутри самого приложения. У приложения по-прежнему есть свои учетные записи и свое представление о том, кто вошел в систему. Если все проходят через прокси и попадают в одну общую учетную запись администратора, у вас есть надежная входная дверь и одна анонимная сессия за ней. Журнал аудита по-прежнему показывает одно имя. Права доступа по-прежнему не могут различаться для разных людей. Называть такую схему SSO — это ошибка безопасности, поскольку история с увольнением сотрудника верна лишь наполовину: удаление человека из вашего IdP закрывает входную дверь, в то время как созданный им внутри приложения API token продолжает работать для любого, кто может получить прямой доступ к приложению.

Обеспечение безопасности аутентификации через заголовки

Некоторые приложения принимают имя пользователя от прокси-сервера, что позволяет реализовать идентификацию пользователей без использования платных решений SSO. В каждом проекте эта настройка называется по-своему.

В Grafana эта функция называется auth proxy и поставляется в выключенном состоянии. Имя заголовка по умолчанию — X-WEBAUTH-USER, и вы можете указать любой заголовок, который устанавливает ваш прокси.

[auth.proxy]
enabled = true
header_name = X-authentik-username
header_property = username
auto_sign_up = true
whitelist = 10.0.0.5

whitelist — это строка, которую часто пропускают. Документация Grafana прямо указывает, что она нужна для предотвращения подмены заголовков пользователями, поэтому в ней должен быть указан только адрес вашего прокси. В Gitea реализована аналогичная функция под другими названиями, и она поставляется с более безопасными настройками по умолчанию.

[security]
ENABLE_REVERSE_PROXY_AUTHENTICATION = true
REVERSE_PROXY_AUTHENTICATION_USER = X-WEBAUTH-USER
REVERSE_PROXY_TRUSTED_PROXIES = 10.0.0.5/32
REVERSE_PROXY_LIMIT = 1

REVERSE_PROXY_TRUSTED_PROXIES по умолчанию имеет значение 127.0.0.0/8,::1/128, а REVERSE_PROXY_LIMIT определяет количество прокси, которым Gitea будет доверять в цепочке. Установка этого лимита в ноль полностью отключает обработку заголовков.

Paperless-ngx предлагает PAPERLESS_ENABLE_HTTP_REMOTE_USER вместе с PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME, и в документации к нему приведено предупреждение, актуальное для всех подобных настроек:

Это позволит выполнять аутентификацию простым добавлением заголовка Remote-User: <username> к запросу. Используйте с осторожностью!

Безопасность аутентификации через заголовки обеспечивается двумя правилами, и оба касаются доступности. Во-первых, приложение должно быть недоступно напрямую, только через прокси, так как любой, кто может установить соединение с портом приложения, может отправить этот заголовок и войти под любым пользователем. В Docker настройка ports: ["8000:8000"] публикует порт на всех интерфейсах, поэтому привязывайте его к адресу loopback с помощью ports: ["127.0.0.1:8000:8000"] или уберите публикацию порта и поместите прокси в ту же сеть Docker. Во-вторых, прокси должен удалять любую копию заголовка, приходящую от клиента, чтобы приложение видело только то значение, которое установил ваш прокси после аутентификации.

Проверьте оба условия. Выполните первую команду с машины вне вашего VPS, а вторую — на самом сервере.

curl -si -H "Remote-User: admin" http://203.0.113.10:8000/ | head -n 1
ss -ltnp | grep 8000

Команда curl должна завершиться ошибкой подключения, а ss должен вывести 127.0.0.1:8000, а не 0.0.0.0:8000. Если в первой строке вы видите HTTP/1.1 302 Found, это означает, что приложение отвечает напрямую из публичного интернета, поэтому любой может войти под любым пользователем, просто указав его имя в заголовке.

Если нет бесплатного SSO, принимайте решение, а не жалуйтесь

Четыре варианта действий в порядке приоритетности.

  1. Выбирайте приложение с поддержкой OIDC. Если два проекта выполняют одну и ту же задачу, но один из них бесплатно взаимодействует с вашим провайдером идентификации, это дает реальную экономию на эксплуатации.
  2. Используйте forward auth. Для инструмента администрирования с одной учетной записью и одним оператором достаточно прокси перед приложением; идентификация каждого пользователя внутри самого приложения в данном случае ничего не дает.
  3. Платите. Если приложение критически важно для работы, а стоимость лицензии на пользователя соответствует размеру вашей команды, деньги помогут поддерживать проект. Альтернатива — тратить на это свои вечера.
  4. Обратитесь к разработчикам после поиска в баг-трекере. Поддержка OIDC в Vaultwarden появилась благодаря форку от участника сообщества и долгому pull request, поэтому запрос функции с готовой реализацией иногда попадает в бесплатную версию.

Ничего из этого не будет работать без собственного провайдера идентификации, который нужно развернуть в первую очередь. Запуск authentik на VPS позволит получить провайдер OIDC и SAML, а также упомянутый выше outpost для forward auth, а сравнение Keycloak, authentik и Zitadel поможет оценить компромиссы, если вы еще не готовы сделать выбор.

История лицензирования и почему этот пункт включен в чек-лист

Последний пункт чек-листа касается будущего, так как текущая структура уровней — это лишь моментальный снимок. Два хорошо задокументированных примера показывают, как быстро меняется ситуация в обе стороны. 10 августа 2023 года HashiCorp приняла лицензию Business Source License 1.1 для всех будущих релизов, в то время как более ранние версии остались под MPL 2.0 (Mozilla Public License). В марте 2024 года Redis перешла на SSPL (Server Side Public License), а 1 мая 2025 года объявила, что Redis 8 также выпускается под AGPLv3 (GNU Affero General Public License).

Рассматривайте оба случая как доказательство механизма, а не мотива. Лицензия, которую вы читаете сегодня, применяется к версии, которую вы устанавливаете сегодня, и проект, владеющий всеми авторскими правами, может самостоятельно изменить условия следующего релиза. Именно поэтому вопрос о CLA включен в чек-лист: широкая передача авторских прав — это то, что делает возможным одностороннее изменение лицензии.

Самостоятельно проверяйте историю проекта, прежде чем строить на нем свою инфраструктуру.

git clone --filter=blob:none https://github.com/paperless-ngx/paperless-ngx.git
cd paperless-ngx
git log --follow --oneline -- LICENSE

Короткий список коммитов, состоящий в основном из первого импорта, — хороший знак. Несколько правок файла лицензии означают, что вам следует изучить каждое сообщение коммита, прежде чем планировать работу с учетом текущих условий.

FAQ

Что такое «налог на SSO»?

«Налог на SSO» — это практика взимания платы за функцию единого входа (single sign-on) как за премиальную возможность, в то время как остальной продукт предоставляется бесплатно или по низкой цене. В self-hosted ПО это выглядит как open source приложение, которое можно запустить без лицензионного ключа, но где поддержка OIDC или SAML доступна только в платной версии. Название происходит от «Стены позора SSO» (SSO Wall of Shame) на сайте sso.tax, где отслеживаются поставщики, требующие значительную доплату за эту функцию. Для администратора self-hosted систем это означает, что каждое приложение хранит собственную базу пользователей, поэтому учетные записи приходится создавать и удалять вручную.

Является ли reverse proxy с forward auth тем же самым, что и SSO?

Нет. Forward auth защищает «входную дверь»: ваш прокси проверяет пользователя у провайдера идентификации до того, как запрос попадет в приложение. Само приложение при этом продолжает использовать собственные учетные записи. Если все пользователи попадают на одну общую страницу входа, вы получаете единую анонимную сессию и журнал аудита, в котором фигурирует только одно имя. Полноценная идентификация каждого пользователя возможна только тогда, когда приложение считывает имя пользователя из заголовка. Это умеют делать auth proxy в Grafana, reverse proxy authentication в Gitea и PAPERLESS_ENABLE_HTTP_REMOTE_USER в Paperless-ngx. Эти настройки безопасны только в том случае, если к приложению нельзя обратиться в обход прокси, так как заголовок представляет собой обычную строку, которую может отправить любой клиент.

Какие self-hosted приложения включают OIDC в бесплатную версию?

Проверено по документации проектов в августе 2026 года: Paperless-ngx, Planka, BookStack, Gitea, listmonk и Vaultwarden поддерживают OIDC в своих бесплатных сборках, а GitLab Self-Managed относит SAML к уровню Free. Open source сборка Grafana поддерживает стандартный OAuth для вашего собственного провайдера, в то время как SAML там является функцией Enterprise. Перед установкой уточняйте информацию на странице аутентификации конкретного проекта, так как эти списки меняются с выходом новых релизов.

Стоит ли платить за тариф, открывающий единый вход?

Примите решение, исходя из двух показателей: сколько людей нуждаются в учетных записях и сколько приложений вам пришлось бы обслуживать вручную. Для одного или двух администраторов достаточно forward auth перед локальной учетной записью, и платная версия дает мало преимуществ. Для команды, где люди приходят и уходят, одна забытая при увольнении учетная запись стоит дороже, чем лицензия, а оплата финансирует поддержку проекта, на который вы полагаетесь. Если цена не устраивает, практичнее выбрать приложение, которое включает OIDC, вместо того чтобы искать обходные пути для того, где этой функции нет.