Podatek od SSO w oprogramowaniu self-hosted
Analiza powodów blokowania OIDC oraz SAML w darmowych wersjach oprogramowania. Sprawdź, dlaczego dostawcy stosują ten model i na co zwrócić uwagę przed instalacją aplikacji.
Czym jest podatek od SSO
Podatek od SSO w oprogramowaniu typu self-hosted to model, w którym aplikacja jest darmowa, a jedyną funkcją wymagającą opłaty jest jednokrotne logowanie (SSO). Całość można uruchomić na własnym serwerze VPS bez klucza licencyjnego i limitów użytkowników. Następnie, po otwarciu strony dotyczącej uwierzytelniania w dokumentacji, okazuje się, że OpenID Connect (OIDC) lub SAML (security assertion markup language) są dostępne wyłącznie w płatnym planie.
Ma to większe znaczenie niż typowa funkcja za paywallem, ponieważ to właśnie SSO sprawia, że zestaw usług self-hosted zachowuje się jak jeden system. Dostawca tożsamości (IdP) zapewnia jedno konto dla każdej osoby, jedną politykę haseł, jedno miejsce do włączenia uwierzytelniania wieloskładnikowego (MFA) oraz jedno miejsce do zablokowania dostępu użytkownikowi. Bez tego każda aplikacja utrzymuje własną, odrębną bazę użytkowników, a każdą z nich trzeba zarządzać ręcznie.
Model ten jest na tyle stary, że doczekał się publicznego zestawienia. "SSO Wall of Shame" pod adresem sso.tax wymienia dostawców, którzy pobierają wysokie opłaty za jednokrotne logowanie. Wpisy sięgają 2018 roku, a autor stosuje sprawiedliwe kryterium: "Jeśli wsparcie dla SSO podnosi cenę o 10%, nie trafiasz na tę listę". Większość pozycji na tej liście to oprogramowanie zamknięte. Ta sama logika cenowa pojawia się obecnie w projektach open source, które hostuje się samodzielnie.
Dlaczego opiekunowie projektów przenoszą logowanie jednokrotne (SSO) do płatnych planów
Istnieją dwa powody i oba są uczciwe. Utrzymanie SSO jest kosztowne, a jednocześnie jest to jedna z niewielu funkcji, za którą duże organizacje są skłonne zapłacić.
Koszty wsparcia są realne, ponieważ integracja tożsamości nigdy nie jest w pełni ukończona. Każdy dostawca tożsamości (IdP) formatuje swoje oświadczenia (claims) w nieco inny sposób. Mapowanie grup, czas życia sesji, adresy URL przekierowań oraz różnice w synchronizacji czasu (clock skew) generują błędy logowania. Błąd logowania blokuje dostęp wszystkim użytkownikom jednocześnie, dlatego zgłoszenia tego typu są traktowane priorytetowo. Następnie pojawiają się kolejne wymagania: zagnieżdżone grupy, mapowanie ról, automatyczne udostępnianie kont za pomocą SCIM (System for Cross-domain Identity Management) oraz dzienniki audytu, które będą analizowane przez zespoły ds. zgodności (compliance).
Aspekt przychodowy wynika z matematyki, a nie ze złej woli. Firma, która nie może połączyć aplikacji z własnym IdP, w ogóle jej nie wdroży. SSO wyznacza zatem wyraźną granicę między użytkownikiem płacącym a niepłacącym. Projekt typu open core musi taką granicę gdzieś wyznaczyć. SSO pasuje do tego celu lepiej niż niemal każda inna funkcja, dlatego tak wiele projektów wybiera właśnie to rozwiązanie.
Jedna uwaga dotycząca częstych narzekań: przed założeniem, że funkcja została usunięta, należy sprawdzić changelog, ponieważ usunięcie zawsze pojawia się w informacjach o wydaniu (release notes). W projektach, które przeanalizowałem na potrzeby tego wpisu, płatne funkcje SSO były od początku projektowane dla płatnych wersji. Nie znalazłem przypadku, w którym działające darmowe SSO zostałoby wycofane. Przykładem jest Grafana. Na stronie dotyczącej SAML znajduje się krótka informacja: "Available in Grafana Enterprise and Grafana Cloud", podczas gdy ogólne uwierzytelnianie OAuth z własnym dostawcą działa w wersji open source.
Rzeczywisty koszt podatku SSO
Pieniądze to mniejsza część problemu. Płatne plany są sprzedawane w przeliczeniu na użytkownika, więc rachunek rośnie wraz z zespołem, podczas gdy hosting i aktualizacje pozostają Twoim obowiązkiem.
Większy koszt to ręczne zarządzanie tożsamościami, które obciąża cztery obszary.
- Jeden magazyn haseł na aplikację, co sprawia, że jedno ponownie użyte hasło stanowi lukę w każdej aplikacji, która je współdzieli.
- Usuwanie dostępu z pamięci. Musisz pamiętać o każdej usłudze, z której korzystała dana osoba, a ta, o której zapomnisz, jest zazwyczaj najważniejsza.
- MFA konfigurowane osobno dla każdej aplikacji, o ile dana aplikacja w ogóle je wspiera.
- Współdzielone loginy, co w rzeczywistości dzieje się w małych zespołach pod taką presją.
Ostatni punkt zasługuje na osobne omówienie. Gdy zespół współdzieli jedno konto administratora w menedżerze dokumentów, ścieżka audytu rejestruje jedną nazwę dla wszystkich działań, więc nie można ustalić, kto usunął fakturę. Uprawnienia przypisane do użytkownika również przestają działać, ponieważ istnieje tylko jeden użytkownik. To jest rzeczywista szkoda wynikająca z podatku SSO: zmusza on małe zespoły do korzystania z jednego współdzielonego konta, co jest gorszym rozwiązaniem niż jakakolwiek inna alternatywa.
Lista kontrolna przed wdrożeniem jakiegokolwiek rozwiązania
Wykonaj te kroki przed docker compose up, a nie po tym, jak aplikacja będzie zawierać 400 dokumentów.
- Otwórz stronę uwierzytelniania w dokumentacji i przeczytaj notatkę o poziomach dostępu na górze. Funkcje płatne są oznaczone plakietką lub krótką informacją o dostępności.
- Potwierdź, że aplikacja obsługuje OIDC lub SAML dla własnego dostawcy tożsamości, zamiast ograniczać się do sztywnej listy publicznych dostawców.
- Sprawdź mapowanie ról i grup. Utworzenie użytkownika to połowa zadania, a ręczne przypisywanie uprawnień w dziesięciu aplikacjach to ta część, która sprawia problemy.
- Sprawdź, czy aplikacja akceptuje uwierzytelnioną nazwę użytkownika w nagłówku z zaufanego proxy oraz czy można wskazać, któremu proxy ufa.
- Przejrzyj historię licencji w git i sprawdź, czy współtwórcy podpisują CLA (contributor licence agreement).
- Sprawdź procedurę wyrejestrowania użytkownika (offboarding). Dowiedz się, co dzieje się z tokenami API (application programming interface) oraz aktywnymi sesjami po wyłączeniu konta w IdP.
Punkt 2 jest źródłem największych rozczarowań. Przycisk "Sign in with Google" nie jest obsługą OIDC dla Twojego dostawcy tożsamości: to sztywna integracja z jednym konkretnym dostawcą. Prawdziwa obsługa wymaga podania adresu URL wystawcy (issuer URL), a cała reszta jest pobierana automatycznie poprzez mechanizm discovery. Możesz potwierdzić poprawność konfiguracji po stronie dostawcy za pomocą jednego polecenia.
curl -s https://id.example.com/.well-known/openid-configuration \
| jq '.issuer, .authorization_endpoint, .token_endpoint'Poprawnie działający dostawca zwraca trzy adresy URL. Pusty wynik lub błąd 404 zazwyczaj oznaczają błędną ścieżkę discovery, która jest specyficzna dla dostawcy: Keycloak publikuje ją pod adresem /realms/<realm>/.well-known/openid-configuration. Jeśli aplikacja nie posiada pola na adres URL wystawcy, nie będzie w stanie komunikować się z Twoim IdP, niezależnie od tego, co podaje lista funkcji.
Punkt 6 staje się problemem kilka tygodni po odejściu pracownika. Wyłączenie konta w IdP blokuje możliwość logowania. Nie powoduje to jednak unieważnienia tokena API wydanego wcześniej przez aplikację, ponieważ aplikacja weryfikuje ten token samodzielnie i nie odpytuje o niego IdP. Dlatego proces wyrejestrowania składa się z dwóch kroków: wyłączenia konta w IdP oraz usunięcia użytkownika lub jego tokenów wewnątrz każdej aplikacji.
Co faktycznie oznaczają odznaki poziomów
Informacje te zostały zweryfikowane na podstawie dokumentacji poszczególnych projektów w sierpniu 2026 roku. Należy zacząć od wersji płatnych.
Grafana publikuje informacje o SAML jako „Dostępne w Grafana Enterprise i Grafana Cloud”, wraz z synchronizacją zespołów i provisioningiem SCIM. Generic OAuth, GitHub OAuth, LDAP (lightweight directory access protocol) oraz auth proxy znajdują się w wersji open source, więc użytkownik hostujący usługę samodzielnie może logować się za pośrednictwem własnego dostawcy. Płatna granica przebiega w miejscu SAML, a nie SSO jako całości, co jest niuansem, który określenie „podatek od SSO” zazwyczaj pomija.
Metabase jest bardziej bezpośredni. Dokumentacja stwierdza: „Uwierzytelnianie SAML jest dostępne tylko w planach Pro i Enterprise (zarówno w wersji self-hosted, jak i w Metabase Cloud)”. Wersja open source zachowuje logowanie hasłem oraz LDAP.
Passbolt oznacza swoją dokumentację SSO jako Pro i Cloud, więc wersja community nie posiada tej funkcji. Udokumentowani dostawcy obejmują Keycloak oraz Entra ID.
Teraz druga strona, ponieważ ten schemat nie jest uniwersalny.
- GitLab Self-Managed posiada oznaczenie „Tier: Free, Premium, Ultimate” na stronie SAML, więc korzystanie z SAML w ramach własnej instancji GitLab jest bezpłatne.
- Paperless-ngx konfiguruje OIDC poprzez django-allauth za pomocą
PAPERLESS_SOCIALACCOUNT_PROVIDERS, ukrywa lokalny formularz logowania za pomocąPAPERLESS_DISABLE_REGULAR_LOGINi mapuje oświadczenia (claims) na grupy za pomocąPAPERLESS_SOCIAL_ACCOUNT_SYNC_GROUPS. - Planka przyjmuje
OIDC_ISSUER,OIDC_CLIENT_IDorazOIDC_CLIENT_SECRET, domyślnie ustawia zakresy (scopes) naopenid profile emaili nadaje uprawnienia administratora na podstawie oświadczenia roli za pomocąOIDC_ADMIN_ROLES. - BookStack przełącza się za pomocą
AUTH_METHOD=oidc, a następnie mapuje grupy dostawcy na własne role za pomocąOIDC_USER_TO_GROUPS=trueorazOIDC_GROUPS_CLAIM. - Vaultwarden wprowadził „wsparcie dla SSO z OpenID Connect” w wersji 1.35.0 w dniu 27 grudnia 2025 roku, na podstawie pull requesta od współtwórcy, który wcześniej utrzymywał tę funkcję w forku.
- listmonk posiada logowanie OIDC wraz z rolami użytkowników od wersji v4.0.0.
Należy korzystać z tych informacji podczas wyboru, a nie po podjęciu decyzji. Tablica kanban Planka oraz inne alternatywy Trello do hostowania samodzielnego nie traktują tożsamości w ten sam sposób, podobnie jak BookStack, Wiki.js i Outline. Darmowe OIDC to funkcja, którą można oceniać tak samo jak limity pamięci czy klienty mobilne. Jeśli lista jest wciąż w fazie tworzenia, co hostować samodzielnie w 2026 stanowi rozsądny punkt wyjścia, a zarówno menedżer dokumentów Paperless-ngx, jak i Vaultwarden oferują darmowe OIDC już dziś.
Dlaczego reverse proxy przed aplikacją nie jest rozwiązaniem single sign-on
Powszechnym obejściem jest forward auth. Reverse proxy wstrzymuje każde żądanie, pyta usługę uwierzytelniania, czy dana przeglądarka jest zalogowana, a dopiero po uzyskaniu potwierdzenia przekazuje żądanie do aplikacji. authentik nazywa to dostawcą proxy (proxy provider), oferując tryb forward auth dla pojedynczej aplikacji oraz dla całej domeny. Authelia i oauth2-proxy wykonują to samo zadanie.
Blok witryny w Caddy wygląda następująco, zgodnie z przykładem dostarczonym przez 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
}Wielkość liter w nazwach nagłówków ma w Caddy znaczenie, ponieważ niedopasowana nazwa spowoduje przekazanie pustej wartości. Przy każdym zatwierdzonym żądaniu outpost ustawia X-authentik-username, X-authentik-email, X-authentik-groups oraz kilka innych.
Oto co się dzięki temu zyskuje. Nikt nie uzyska dostępu do aplikacji bez wcześniejszego przejścia przez dostawcę tożsamości, dzięki czemu niezałatany formularz logowania nie jest już wystawiony na działanie Internetu, a MFA ma zastosowanie do wszystkiego, co znajduje się za proxy.
Oto czego się dzięki temu nie zyskuje: tożsamości wewnątrz aplikacji. Aplikacja nadal posiada własne konta i własną definicję tego, kto jest zalogowany. Jeśli wszyscy przechodzą przez proxy i trafiają na jedno współdzielone konto administratora, uzyskuje się solidne drzwi wejściowe, za którymi kryje się jedna anonimowa sesja. Dziennik audytu nadal pokazuje tylko jedną nazwę. Uprawnienia nadal nie mogą różnić się w zależności od użytkownika. Nazywanie takiej konfiguracji SSO jest błędem w zabezpieczeniach, ponieważ proces wyrejestrowania użytkownika jest tylko częściowo skuteczny: usunięcie osoby z IdP zamyka drzwi wejściowe, podczas gdy utworzony przez nią wewnątrz aplikacji token API nadal działa dla każdego, kto może uzyskać bezpośredni dostęp do aplikacji.
Zabezpieczanie uwierzytelniania przez nagłówki
Niektóre aplikacje akceptują nazwę użytkownika przekazaną z proxy, co pozwala na identyfikację użytkownika bez płatnego SSO. Nazwa tego ustawienia różni się w zależności od projektu.
Grafana nazywa to auth proxy i domyślnie wyłącza tę funkcję. Nazwa nagłówka to domyślnie X-WEBAUTH-USER; można ją wskazać na dowolny nagłówek ustawiany przez proxy.
[auth.proxy]
enabled = true
header_name = X-authentik-username
header_property = username
auto_sign_up = true
whitelist = 10.0.0.5whitelist to parametr, który często jest pomijany. Dokumentacja Grafana wyraźnie wskazuje, że służy on do zapobiegania podszywaniu się użytkowników pod nagłówek, dlatego powinien zawierać wyłącznie adres IP proxy. Gitea posiada tę samą funkcję pod inną nazwą i jest dostarczana z bezpieczniejszymi ustawieniami domyślnymi.
[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 = 1REVERSE_PROXY_TRUSTED_PROXIES domyślnie przyjmuje wartość 127.0.0.0/8,::1/128, a REVERSE_PROXY_LIMIT określa liczbę zaufanych proxy w łańcuchu. Ustawienie tego limitu na zero całkowicie wyłącza obsługę nagłówków.
Paperless-ngx oferuje PAPERLESS_ENABLE_HTTP_REMOTE_USER wraz z PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME, a dokumentacja zawiera ostrzeżenie, które dotyczy wszystkich tego typu ustawień:
Pozwoli to na uwierzytelnienie poprzez proste dodanie nagłówka Remote-User: <username> do żądania. Należy zachować ostrożność!
Dwie zasady zapewniają bezpieczeństwo uwierzytelniania przez nagłówki i obie dotyczą dostępności sieciowej. Po pierwsze, aplikacja musi być niedostępna poza proxy, ponieważ każdy, kto może nawiązać z nią połączenie, może wysłać taki nagłówek i podszyć się pod dowolnego użytkownika. W Docker, ports: ["8000:8000"] publikuje port na wszystkich interfejsach, dlatego należy powiązać go z adresem loopback za pomocą ports: ["127.0.0.1:8000:8000"] lub usunąć publikację portu i umieścić proxy w tej samej sieci Docker. Po drugie, proxy musi usuwać każdą kopię nagłówka nadesłaną przez klienta, aby aplikacja otrzymywała wyłącznie wartość ustawioną przez proxy po uwierzytelnieniu.
Sprawdź oba warunki. Wykonaj pierwsze polecenie z maszyny spoza VPS, a drugie bezpośrednio na serwerze.
curl -si -H "Remote-User: admin" http://203.0.113.10:8000/ | head -n 1
ss -ltnp | grep 8000Polecenie curl powinno zakończyć się niepowodzeniem, a ss powinno zwrócić 127.0.0.1:8000 zamiast 0.0.0.0:8000. Pierwsza linia o treści HTTP/1.1 302 Found oznacza, że aplikacja odpowiada bezpośrednio na żądania z publicznego Internetu, co pozwala każdemu zalogować się jako dowolny użytkownik poprzez wskazanie go w nagłówku.
Gdy brak darmowego SSO, podejmij decyzję zamiast narzekać
Cztery opcje, w kolejności, w jakiej bym je wypróbował.
- Wybierz aplikację, która zawiera OIDC. Jeśli dwa projekty wykonują to samo zadanie, a jeden z nich komunikuje się z Twoim dostawcą tożsamości za darmo, stanowi to realną różnicę w kosztach utrzymania.
- Użyj forward auth zgodnie z przeznaczeniem. W przypadku narzędzia administracyjnego z jednym kontem i jednym operatorem, wystarczy proxy przed aplikacją, a tożsamość per użytkownik wewnątrz aplikacji nie przynosi żadnych korzyści.
- Zapłać. Jeśli aplikacja jest kluczowa dla Twojej pracy, a cena za stanowisko mieści się w budżecie zespołu, pieniądze te pozwalają utrzymać projekt, a alternatywą jest poświęcanie własnych wieczorów.
- Zapytaj twórców, po uprzednim przeszukaniu trackera zgłoszeń. Obsługa OIDC w Vaultwarden pojawiła się dzięki fork'owi użytkownika i długotrwałemu pull request, więc prośba o funkcję poparta gotową implementacją czasami trafia do darmowej edycji.
Nic z tego nie zadziała bez własnego dostawcy tożsamości, co jest elementem, który należy zbudować w pierwszej kolejności. Uruchamianie authentik na VPS zapewnia dostawcę OIDC i SAML oraz wykorzystany powyżej outpost forward auth, a porównanie Keycloak, authentik i Zitadel omawia wady i zalety, jeśli nie chcesz jeszcze podejmować ostatecznej decyzji.
Historia licencji i powody jej uwzględnienia na liście kontrolnej
Ostatni punkt listy kontrolnej dotyczy przyszłości, ponieważ obecny układ warstw jest tylko migawką stanu faktycznego. Dwa dobrze udokumentowane przypadki pokazują, jak szybko zmienia się sytuacja w obu kierunkach. Firma HashiCorp przyjęła licencję Business Source License 1.1 dla wszystkich przyszłych wydań w dniu 10 sierpnia 2023 r., podczas gdy wcześniejsze wersje pozostały na licencji MPL 2.0 (Mozilla Public License). Redis przeszedł na licencję SSPL (Server Side Public License) w marcu 2024 r., a następnie 1 maja 2025 r. ogłosił, że Redis 8 będzie również dystrybuowany na licencji AGPLv3 (GNU Affero General Public License).
Oba przypadki należy traktować jako dowód na działanie mechanizmu, a nie jako analizę motywów. Licencja, z którą zapoznajesz się dzisiaj, dotyczy wersji instalowanej dzisiaj, a projekt posiadający pełnię praw autorskich może samodzielnie zmienić warunki kolejnego wydania. Dlatego pytanie o CLA znajduje się na liście kontrolnej, ponieważ szerokie przeniesienie praw autorskich jest tym, co umożliwia jednostronną zmianę licencji.
Przed rozpoczęciem prac w oparciu o dany projekt, samodzielnie sprawdź jego historię.
git clone --filter=blob:none https://github.com/paperless-ngx/paperless-ngx.git
cd paperless-ngx
git log --follow --oneline -- LICENSEKrótka lista commitów, pochodząca głównie z pierwszego importu, jest dobrym sygnałem. Kilkukrotne nadpisanie pliku licencji oznacza, że przed zaplanowaniem prac w oparciu o obecne warunki należy przeczytać każdy komunikat commitu.
FAQ
Czym jest podatek SSO?
Podatek SSO to praktyka pobierania opłat za funkcję logowania jednokrotnego (Single Sign-On) jako opcję premium, podczas gdy reszta produktu jest darmowa lub tania. W oprogramowaniu typu self-hosted wygląda to jak aplikacja open source, którą można uruchomić bez klucza licencyjnego, ale w której obsługa OIDC lub SAML znajduje się w płatnym pakiecie. Nazwa pochodzi od strony SSO Wall of Shame pod adresem sso.tax, która śledzi dostawców pobierających wysokie opłaty za tę funkcję. Konsekwencją dla użytkownika self-hosted jest to, że każda aplikacja utrzymuje własną bazę użytkowników, więc konta muszą być tworzone i usuwane ręcznie.
Czy reverse proxy z forward auth to to samo co SSO?
Nie. Forward auth chroni wejście: proxy sprawdza tożsamość u dostawcy przed przekazaniem żądania do aplikacji. Aplikacja znajdująca się za proxy nadal korzysta z własnych kont, więc jeśli wszyscy użytkownicy trafiają na jeden wspólny ekran logowania, powstaje pojedyncza anonimowa sesja i dziennik audytu z jedną nazwą użytkownika. Prawdziwa tożsamość dla każdego użytkownika pojawia się dopiero wtedy, gdy aplikacja odczytuje nazwę użytkownika z nagłówka, co potrafią m.in. auth proxy w Grafana, reverse proxy authentication w Gitea oraz PAPERLESS_ENABLE_HTTP_REMOTE_USER w Paperless-ngx. Te ustawienia są bezpieczne tylko wtedy, gdy aplikacja jest dostępna wyłącznie przez proxy, ponieważ nagłówek jest zwykłym ciągiem znaków, który może wysłać każdy klient.
Które aplikacje self-hosted zawierają OIDC w darmowej wersji?
Stan na sierpień 2026 roku, na podstawie dokumentacji projektów: Paperless-ngx, Planka, BookStack, Gitea, listmonk oraz Vaultwarden obsługują OIDC w darmowych kompilacjach, a GitLab Self-Managed wymienia SAML w pakiecie Tier: Free. Otwarta wersja Grafana obsługuje ogólny OAuth z własnym dostawcą tożsamości, natomiast SAML jest tam funkcją Enterprise. Przed instalacją należy sprawdzić stronę poświęconą uwierzytelnianiu w danym projekcie, ponieważ listy te zmieniają się wraz z kolejnymi wydaniami.
Czy warto płacić za pakiet odblokowujący logowanie jednokrotne?
Decyzję należy podjąć w oparciu o dwie liczby: ilu użytkowników potrzebuje kont oraz ilu aplikacjami trzeba by zarządzać ręcznie w przeciwnym razie. Dla jednego lub dwóch administratorów forward auth przed lokalnym kontem jest wystarczające i płatny pakiet niewiele wnosi. W przypadku zespołu, w którym ludzie dołączają i odchodzą, jedno konto pominięte podczas usuwania uprawnień kosztuje więcej niż licencja, a opłata finansuje utrzymanie oprogramowania, z którego korzystasz. Jeśli cena nie jest akceptowalna, praktycznym rozwiązaniem jest wybór aplikacji zawierającej OIDC zamiast obchodzenia ograniczeń w tej, która go nie posiada.