Single Sign-On for a Self-Hosted Stack With authentik
Six self-hosted apps usually means six separate logins. Here is how to put one open-source identity provider in front of Chatwoot, Twenty, Cal.com, Plausible, listmonk and Formbricks, what SSO really costs per app, and when it is not worth it.

Running Chatwoot, Twenty, Cal.com, Plausible, listmonk and Formbricks on your own servers means six separate user databases, six password policies, and six offboarding checklists. The fix is one open-source identity provider, authentik, that every app trusts for login. The catch, and the part most guides skip, is that three of these six apps cannot do SSO at all, and two more charge enterprise prices for it. This post maps exactly what each app supports, shows the three ways to connect them, and works out what SSO actually costs.
Why six apps create six identity problems
Each self-hosted app ships with its own local accounts. That is fine on day one and painful by month three:
- Joiners and leavers: hiring someone means creating six accounts. When someone leaves, you must disable six accounts. Miss one and a former employee keeps access to your support inbox or CRM.
- MFA coverage is uneven: some of these apps have no two-factor support at all in their community editions, so your security posture is set by the weakest app.
- Password policy drift: each app has its own rules, its own reset flow, and its own session length. Users respond by reusing passwords.
- No central audit: when a client or auditor asks who had access to what, you are exporting user lists from six admin panels.
One identity provider (IdP) collapses all of this into a single user directory, one MFA policy, one offboarding switch, and one login log. The question is how each app connects to it, and that is where the honest answer gets messy.
The SSO audit: what each app actually supports
Before choosing an IdP, audit what your apps can consume. Here is the current state of the six apps we deploy most often, checked against vendor pricing pages and docs in October 2026.
Chatwoot. The Community Edition is free and has no SSO. SAML and OIDC single sign-on sit on the self-hosted Enterprise plan at $99 per agent per month. For a 10-seat support team, turning on SSO the official way costs $990 a month. If you are running self-hosted Chatwoot after leaving Zendesk, that line item matters.
Twenty. SAML and OIDC SSO are included from the Organization plan at $19 per user per month on Twenty Cloud. If you are weighing that against a self-hosted deployment, our HubSpot to Twenty migration guide covers the wider cost and data questions.
Cal.com. Cal.com supports both SAML and OIDC. OIDC needs a client ID, client secret and well-known URL, configured in the organization SSO settings. On the hosted product, SSO is part of the Organizations plan at $28 per user per month.
Formbricks. OIDC support exists and is documented, with plain environment variables, but the docs state clearly: OpenID Connect is part of the Formbricks Enterprise Edition. Self-hosting the free edition does not get you SSO.
listmonk. listmonk has no OIDC or SAML support at all. What it does have is unusually good documentation for putting an auth proxy in front of it: the docs list exactly which routes are private admin endpoints (/api/*, /admin/*) and which are public (subscription pages, tracked links, tracking pixels). If you migrated from Mailchimp to listmonk, this is how you protect the admin side. Keep the public routes genuinely public, though: deliverability depends on tracked opens and clicks resolving, which is why our self-hosted email deliverability guide pairs well with this section.
Plausible Community Edition. Plausible CE has no SSO and no team management; community deployments have documented the gap and even written their own OIDC patches. The CE feature set is deliberately smaller than the cloud product, as independent deployment guides confirm.
The pattern: two apps speak OIDC but gate it (Twenty, Cal.com on their hosted tiers; Formbricks on Enterprise Edition), one charges enterprise seat prices for it (Chatwoot), and two cannot participate in SSO at all (listmonk, Plausible CE). A single IdP with a proxy mode covers all three cases.
authentik vs Keycloak for a small stack
The two serious open-source IdPs are Keycloak and authentik. Both speak OIDC, SAML and LDAP. For a 5 to 50 person stack, we recommend authentik, for three reasons.
First, footprint. Keycloak's own sizing guide budgets 1250 MB of base memory per pod before you log a single user in, allocates 70 percent of the container memory limit to heap, and tells you to leave 150 percent CPU headroom. That is sensible engineering for a bank login portal and heavy machinery for a 20-person tool stack. authentik's maintainers recommend Docker Compose for small setups and it runs comfortably next to other services on a modest VPS.
Second, the proxy provider. authentik can sit in front of an application that has no SSO support and enforce login at the reverse-proxy layer. That one feature is what makes listmonk and Plausible CE solvable without forking them. Keycloak has no equivalent built in; you would add a separate component such as OAuth2 Proxy or Pomerium.
Third, day-to-day administration. authentik's flows and policies model is easier to reason about for small teams, and the project is actively developed under the MIT license with over 25,000 GitHub stars. The project also keeps maturing on the protocol side: as of the 2026.8 release authentik is officially OpenID Certified, and its proxy outpost has been rewritten in Rust for lower resource use. One 2026.8 change worth knowing before you deploy: authentik now only trusts forwarded headers like X-Forwarded-Proto from configured trusted proxy networks, so set that correctly when you put it behind your reverse proxy.
Choose Keycloak instead when you already run it, when you need its fine-grained authorization services, or when an enterprise support contract for the IdP itself is a hard requirement. For everyone else, authentik is the lighter path.
Three ways an app can consume one identity
1. Native OIDC
The clean path. The app redirects to authentik, authentik authenticates the user (with MFA if you enforce it), and returns a signed token. Formbricks shows how simple the wiring is once you have the Enterprise Edition: create an OIDC provider in authentik, then set four environment variables:
OIDC_CLIENT_ID=59cada54-56d4-4aa8-a5e7-5823bbe0e5b7
OIDC_CLIENT_SECRET=your-generated-secret
OIDC_ISSUER=https://auth.example.com/application/o/formbricks/
OIDC_SIGNING_ALGORITHM=RS256
OIDC_DISPLAY_NAME=Company SSO
The redirect URI on the authentik side must match exactly what the app expects; for Formbricks v5.2 and later that is {WEBAPP_URL}/api/auth/oauth2/callback/openid. Cal.com's OIDC setup is the same shape: client ID, client secret, well-known URL.
2. SAML
Older but universal. You exchange XML metadata between authentik and the app. This is the path Chatwoot's Enterprise plan and Cal.com's organization settings expose. SAML works, but OIDC is easier to debug, so prefer OIDC whenever the app offers both.
3. The proxy provider: SSO for apps with no SSO
authentik's proxy provider exists precisely for applications with no native authentication protocol. An authentik outpost intercepts requests and only forwards authenticated ones, adding headers like X-authentik-username, X-authentik-email and X-authentik-groups so the upstream app knows who arrived. There are three modes:
- Proxy mode: the outpost itself proxies all traffic to one upstream app.
- Forward auth, single application: your existing reverse proxy (Nginx, Traefik, Caddy) serves the app and asks the outpost to check each request.
- Forward auth, domain level: one provider protects many apps under the same parent domain. Convenient, but with a real limit: domain-level mode cannot enforce different authorization rules per app. If only the support team should reach Chatwoot but everyone can reach Plausible, use single-application mode.
This is how listmonk gets SSO. You protect the admin routes the listmonk docs mark as private, and you leave the public routes open so subscription forms, tracked links and tracking pixels keep working for people who will never log in.
Putting it together: the setup sequence
- Reserve a hostname such as
auth.example.comand point it at the server that will run authentik. Treat this machine as tier-zero infrastructure: if the IdP is down, nobody logs in anywhere. - Install authentik with Docker Compose following the project's documentation. Put it behind your reverse proxy with a valid TLS certificate before creating anything else.
- Create groups before users: one group per app per role, for example
chatwoot-agents,crm-users,analytics-viewers. Bind every application you create to groups, never to individual users. - Enforce MFA at the IdP. This is the single biggest win of the whole exercise: apps with no two-factor support of their own now sit behind mandatory MFA.
- Connect the OIDC-capable apps first. One provider per app, exact redirect URIs, test with a non-admin account.
- Add proxy providers for listmonk and Plausible CE. Start with single-application forward auth. In the provider's unauthenticated paths, allow exactly the public routes from the app's documentation and nothing more.
- Run an offboarding drill: disable one test user in authentik and confirm access dies in every app within the session lifetime. This drill is the entire point. Do not skip it.
What SSO actually costs: per-app upgrades vs one IdP
Here is the worked example for a 10-person team, using only the SSO-relevant tier of each product:
- Chatwoot Enterprise (SSO/SAML): 10 agents x $99 = $990 per month
- Twenty Organization (SAML/OIDC SSO): 10 users x $19 = $190 per month
- Cal.com Organizations (SAML SSO): 10 users x $28 = $280 per month
- Formbricks Scale (cloud tier with enterprise auth options): $325 per month
That is roughly $1,785 per month in plan upgrades where SSO is the headline difference. authentik itself is free under the MIT license and runs on the same small VPS class as the rest of the stack, so the marginal infrastructure cost is close to zero.
Two honest caveats. First, those paid tiers bundle more than SSO: service-level agreements, role-based access control, priority support. If you need those, the comparison is not SSO alone. Second, the free path is not free of cost: you operate, patch and back up the IdP yourself. For most teams already self-hosting six applications, that marginal operational load is small next to what they already carry.
When this is the wrong choice
- You have two or three users and low exposure: a shared password manager with per-app MFA where available is simpler and good enough.
- You already pay for tiers that include SSO: if you are on Cal.com Organizations or Twenty Organization anyway, just turn their native SSO on. Do not proxy what already works.
- Nobody will own the IdP: an identity provider is the one service that must not rot. If there is no named person responsible for its updates, backups and monitoring, centralizing auth creates a bigger single point of failure than it removes.
- The apps are public-facing: if external clients log into these tools directly with their own accounts, an internal staff IdP is the wrong shape. You need customer identity (CIAM), which is a different project.
Common mistakes
- Using domain-level forward auth when apps need different rules. authentik's own docs warn that domain-level mode cannot apply per-app authorization. It feels tidy and quietly gives the whole company access to everything.
- Trusting unauthenticated-path regexes without checking the logs. If a pattern fails to compile, authentik skips it and logs a warning; the path stays protected. That fails closed, which is safe, but it means your intended public route silently requires login. Check outpost logs after every change, and click an unsubscribe link and a tracked link in a real listmonk campaign to prove the public paths work.
- Protecting listmonk's public endpoints. Tracking pixels, tracked links and subscription pages must stay open to the internet or your email metrics and signup forms break. The listmonk docs list these routes explicitly; use that list.
- Leaving local logins wide open. Where the app allows it, disable local password login after SSO works, but keep one break-glass local admin account with its credentials in your password vault. You will need it the day the IdP is down.
- No IdP backup or monitoring. authentik's database is now the keys to every app. Back it up on the same schedule as your most important database, and alert on it like one.
Frequently asked questions
Does Chatwoot Community Edition support SSO? No. SAML and OIDC are part of Chatwoot's self-hosted Enterprise plan at $99 per agent per month. The practical alternative for Community Edition is an authentik proxy provider in front of the Chatwoot dashboard.
Is authentik free for commercial use? Yes. The core project is MIT licensed, including the proxy provider, OIDC and SAML support. A small set of enterprise features sits under a separate license, but nothing in this guide requires them.
What is the difference between OIDC and SAML for self-hosted apps? Both delegate login to your identity provider. OIDC is a modern JSON-based protocol that is easier to configure and debug; SAML is older XML-based and more widely supported by enterprise software. Use OIDC whenever the app offers both.
Can I add SSO to an app that does not support it? Yes, with a proxy provider that checks authentication at the reverse-proxy layer before requests reach the app. The limits: the app must only be reachable through the proxy (firewall direct access), and the app will not know about roles unless it can read the headers the proxy adds.
What happens if the identity provider goes down? New logins fail everywhere, which is why the IdP is tier-zero infrastructure. Existing sessions in proxied apps typically continue until they expire. Keep one break-glass local admin account per app, automate backups, and monitor authentik with the same urgency as your production database.
Does one login mean one session across all apps? Mostly. Once a user has an authentik session, apps connected through OIDC or the proxy will not ask for a password again until the session expires. Session lengths are configured per provider, so you can make Chatwoot strict and Plausible relaxed.
Where to go from here
If you already run part of this stack, start with the audit section: list your apps, mark which ones speak OIDC, and proxy the rest. If you would rather have the whole thing deployed and run for you, identity layer included, that is exactly what our managed open-source stack service does: Twenty, Chatwoot, Cal.com, Plausible, listmonk and Formbricks on your infrastructure, with SSO, backups and updates handled. And if you are at a bank or insurer where central identity has to fit into a wider private AI deployment with governance documentation, talk to us about our enterprise work.
About AI Agents Plus Editorial
AI automation expert and thought leader in business transformation through artificial intelligence.



