Authelia: The Lightweight SSO and 2FA Gate for Your Entire Self-Hosted Stack

Authelia: The Lightweight SSO and 2FA Gate for Your Entire Self-Hosted Stack

If you run more than two self-hosted services, you have a problem that has nothing to do with any individual app: every one of them has its own login, its own password store, and its own idea of what "secure" means. Vaultwarden has an account. Your dashboard has an account. The admin panel for your proxy has an account. The odds that all of them share a strong, unique password are low, and the odds that one of them is the weak link that exposes everything are high. Authelia is the tool that fixes this at the architectural level rather than the password level. It sits in front of your reverse proxy and forces a single sign-on plus a second factor before any request reaches the service behind it. Authelia is an open-source, Apache-2.0 licensed single Go binary with roughly 28,000 GitHub stars. It is not a full identity provider in the Keycloak sense — it does not try to be your directory, your SAML bridge, or your tenant manager. It is deliberately narrower: it is the bouncer at the door of your homelab or small-business stack. You point it at an identity backend you already control (a file, SQLite, PostgreSQL, LDAP, or Active Directory), you tell it which URLs require which level of authentication, and it transparently inserts SSO and 2FA into the request path for every protected app. In 2026 it crossed a notable threshold: it became an OpenID Certified OpenID Connect provider in March, which moved it from "reverse-proxy companion" to "something you can wire real OIDC logins into." This is a long, honest teardown of what Authelia delivers, how the forward-auth architecture actually works, how to configure it without locking yourself out, where it stops being the right tool, and precisely where your credentials and sessions go. If you are weighing Authelia against Keycloak or Authentik (both of which we have covered), this article tells you exactly what you gain by going lighter and what you give up.

1. What Authelia Actually Is

Authelia is an authentication and authorization server designed to live in front of a reverse proxy. The reverse proxy (Nginx, Traefik, Caddy, HAProxy, or Envoy) intercepts requests to your protected subdomains. For each request that needs protection, the proxy asks Authelia: "Is this user authenticated, and are they allowed here?" Authelia answers yes or no, and the proxy acts on that answer. The application behind the proxy never sees the unauthenticated request if the answer is no, and sees a verified identity (passed via headers) if the answer is yes. The key mental model is that Authelia is a gate, not a platform. It authenticates users and makes authorization decisions. It does not, by itself, store your company org chart, federate with a partner's IdP, or issue SAML assertions to a third party. That scope discipline is the whole reason it stays small, fast, and easy to reason about. A single Authelia process uses tens of megabytes of RAM, which is why it owns the homelab and edge-deployment niche that a JVM-based IdP never could. Authelia is developed primarily by a small core team led by maintainer nightah, with a community of contributors. It is written in Go, published as a single static binary and as Docker images (authelia/authelia and the GitHub Container Registry mirror ghcr.io/authelia/authelia). There is no hosted version and no paid tier — every feature ships in the one open-source build. That is unusual enough in 2026 to be worth stating plainly: the Apache-2.0 release is the product. There is no "enterprise edition" with the good parts removed.

2. Why Forward Auth, and Why It Matters

The architectural pattern Authelia relies on is called forward authentication (or forward-auth). It is a feature of modern reverse proxies where, before proxying a request to a backend, the proxy makes a sub-request to an authentication service and uses the response to decide what to do. If Authelia returns "authenticated," the proxy forwards the original request, often injecting headers like Remote-User and Remote-Groups so the backend knows who is calling. If Authelia returns "not authenticated," the proxy redirects the user to Authelia's login portal instead. This matters because it decouples authentication from every individual application. You do not need Vaultwarden or your dashboard or your metrics stack to implement SSO — most of them cannot, and that is fine, because Authelia handles it upstream. The app just receives a pre-authenticated request with a trusted header, or it never receives the request at all. For the long tail of self-hosted software that was built with a single admin password and no thought of SSO, this is the only practical way to bolt real authentication onto it without forking the code. The trade is that your security boundary now lives in the proxy-plus-Authelia combination. If you misconfigure the proxy so that a backend is reachable without going through Authelia, you have bypassed your own gate. Authelia's documentation is explicit about this: the protection is only as good as the proxy rules that route through it. This is not a flaw in Authelia; it is the inherent nature of a perimeter model. It is the same reason a firewall does nothing if you leave a port open.

3. Licensing and Project Health

Authelia is licensed under Apache-2.0, one of the most permissive and litigation-safe open-source licenses. There is no open-core split, no feature behind a paywall, no "community vs enterprise" binary. For a self-hoster this means: audit it, fork it, embed it — none of it requires a commercial agreement. This is in deliberate contrast to projects like Directus, which we cover in this same batch, that have moved to source-available licenses with revenue thresholds. Project health is strong. As of September 2026, the project sits around 28,000 to 29,000 stars, ships frequent point releases in the 4.39.x line, and demonstrates the fast-follow patch discipline you want in security software: when a regression lands, a fix often ships within days. For example, v4.39.28 (September 17, 2026) followed v4.39.27 by two days as a same-week maintenance fix. That cadence is a signal that the maintainers treat the auth layer with the seriousness it deserves — a bad release here can lock you out of your entire stack, so rapid correction is a feature, not noise. The most important milestone in the project's recent history is its OpenID Connect certification, earned in March 2026. Before that, Authelia was primarily a forward-auth gate. After it, it can also act as a standards-compliant OIDC provider, meaning applications that speak OIDC (rather than relying on proxy headers) can authenticate directly against Authelia. That broadens its relevance considerably: it is now both the bouncer and, for OIDC-capable apps, the identity source.

4. Installation: Docker Compose as the Baseline

The supported and overwhelmingly most common deployment is Docker Compose. A minimal setup has two pieces: Authelia itself, and a Redis instance for session storage (more on why Redis matters below). A typical compose fragment mounts a configuration.yml and a users_database.yml (if using file-based users), exposes Authelia on an internal network, and keeps it off the public internet except through the proxy. Authelia deliberately does not expose a friendly setup wizard that writes your config for you. Configuration is a single YAML file, configuration.yml, that is the source of truth for identity backends, second factors, access control, session storage, and the OIDC provider. This is a double-edged design: it is fully declarative and version-controllable, which infrastructure people love, but it means your first deployment is a reading-the-docs exercise. The good news is the schema is stable across the 4.x series, and breaking changes are rare and clearly noted in release notes. Because Authelia sits in the authentication path, the upgrade procedure is the same pull-and-restart you use everywhere else, but with one extra rule of hygiene: back up your configuration.yml and your user database (or your LDAP connection settings) before you touch it. You are not doing this because an upgrade is likely to break auth — you are doing it because if anything ever does, you want a known-good config to fall back to rather than a stack you can no longer log into.

5. Identity Backends: Where Users Come From

Authelia does not insist on owning your user directory. It supports several backends, and the right one depends on how many users you have and whether you already run a directory. The simplest is the file-based backend with a users_database.yml. You define users, their password hashes, their TOTP secret, and their group memberships in plaintext YAML. This is perfect for a single-admin homelab or a handful of trusted users. The catch is operational: every new user or password change is a config edit and a restart, and you are storing password hashes in a file next to your config. For one or two people that is fine; for a team it becomes a liability. The more scalable option is a database backend — SQLite for small deployments, PostgreSQL for larger ones. User records live in a managed store, changes do not require restarts, and you get proper concurrency. SQLite keeps the single-binary spirit (no separate server), while PostgreSQL fits naturally if you already run Postgres for other services. The enterprise-shaped option is LDAP or Active Directory. If your organization already has a directory, Authelia can authenticate against it directly, which means your existing accounts and group structure flow into access-control policies without duplication. This is where Authelia stops feeling like a homelab toy and starts feeling like infrastructure: point it at the directory you already trust, and your entire self-hosted stack inherits that directory's accounts and groups. Passwords in the file and database backends are hashed, not stored in cleartext, and Authelia supports standard hashing schemes. The practical security advice is consistent: use a database backend with hashed credentials rather than hand-editing a users file for anything beyond a personal deployment.

6. Second Factors: TOTP, WebAuthn, and Duo

Single-factor authentication is what Authelia exists to upgrade. Out of the box it supports three second factors, and the choice matters for both security and usability. TOTP (time-based one-time passwords, the RFC 6238 standard behind Google Authenticator, Authy, and most authenticator apps) is the default and the most interoperable. Every user can enroll a TOTP secret, and the login flow prompts for the rotating six-digit code. It is universally supported and requires no special hardware, which is why it is the baseline 2FA everyone should have. WebAuthn is the modern, phishing-resistant option. It uses hardware keys (YubiKey and friends) or platform authenticators (Touch ID, Windows Hello) to prove possession of a physical device rather than typing a code that could be intercepted. Because WebAuthn binds the credential to the origin, it is resistant to the phishing attacks that defeat TOTP. For anyone serious about security, WebAuthn is the factor to prefer, and Authelia's support for it is a genuine differentiator over simpler gate tools. Duo is the push-notification option for organizations already using Cisco Duo as their 2FA vendor. Authelia can call the Duo API to send a push approval to a user's phone. There is a cautionary tale embedded in the release history here: v4.39.18 (April 2026) was a targeted patch fixing a Duo API response-code handling bug where a successful push could be misclassified as a failure. If you run Duo, that is exactly the kind of subtle auth bug you want patched promptly — and it illustrates why keeping Authelia current matters more than for, say, a static file server. Critically, 2FA in Authelia is per-user-enrollable and can be required globally or per-policy. A common pattern is to require 2FA for admin subdomains but allow single-factor for low-risk internal tools — though the security-minded default is to require it everywhere, because the whole point of the gate is to raise the floor.

7. Access-Control Policies: The Real Power

The feature that turns Authelia from "a login screen" into "an access-control system" is its policy engine. In configuration.yml you define access_control rules: for a given set of domains (and optionally methods or networks), who is allowed, and at what authentication level. Rules are evaluated top to bottom, first match wins, much like firewall or proxy rules. A practical policy set looks like this in concept: the public status page is open to everyone; the family photo gallery requires any authenticated user; the admin dashboard requires a user in the admins group with 2FA; and anything under internal.example.com from outside the home network requires both 2FA and membership in a specific group. Because groups come from your identity backend (including LDAP groups), you can map organizational structure directly into URL-level authorization without touching the applications. The granularity is the point. Authelia lets you express "this URL, for these users, at this assurance level" as declarative config, and it enforces it consistently across every app behind the proxy. For a self-hoster juggling a dozen services, that is the difference between a stack where each app has its own ad-hoc security and a stack where one policy file governs all of them. The warning is the same as any rule engine: order matters, and a misordered rule can either over-permit or over-deny. The over-deny case is merely annoying (you lock yourself out of a service until you fix the rule); the over-permit case is dangerous. Authelia's docs and community are clear that you should test policy changes against a non-critical subdomain before applying them broadly — a lesson learned the hard way by many first-time operators.

8. Session Storage and Why Redis Shows Up

Authelia needs somewhere to keep session state: once a user logs in, subsequent requests within the session must be recognized without re-authenticating every time. For small deployments, Authelia can store sessions in the same database as the user backend. For anything multi-instance or production-adjacent, the recommended store is Redis. Redis matters for two reasons. First, if you run more than one Authelia instance (for availability), they must share session state, and a shared Redis is how they do it. Second, Redis is an in-memory store with a natural expiry model, which fits session lifetimes well. The operational cost is that Redis is now part of your auth-critical infrastructure: if Redis goes down, existing sessions may not validate and users may be forced to re-authenticate (or, depending on config, be unable to). That is a manageable risk, but it is a real one, and it is why the minimal compose file includes Redis rather than treating it as optional. Session lifetime, idle timeout, and remember-me behavior are all configurable. A tighter session policy (shorter expiry, enforced re-auth for admin routes) improves security at the cost of more frequent logins. There is no universal right answer; the recommendation is to tune session length to the sensitivity of what the gate protects.

9. Wiring It to a Reverse Proxy

Authelia is useless without a proxy that speaks forward-auth, and the integration is where most first-time pain lives. Each proxy has its own idiom for sub-requests to an auth server, and Authelia documents each: the Nginx auth_request directive, the Traefik forwardAuth middleware, the Caddy forward_auth directive, HAProxy's oauth2_proxy-style setup, and Envoy's external authorization filter. The pattern is consistent: the proxy is configured so that requests to protected hosts trigger an authentication sub-request to Authelia's /api/verify endpoint. If Authelia responds that the session is valid, the proxy passes the request through (optionally with identity headers). If not, it redirects to Authelia's portal at /, where the user logs in, completes 2FA, and is then redirected back to the originally requested URL with a valid session cookie. The single most common failure mode is the 30-second call drop or the infinite redirect loop, and almost always it traces back to STUN/TURN-style misconfiguration of the auth endpoint URL, cookie domain, or the proxy not forwarding the right headers. The fix is methodical: verify that the auth sub-request reaches Authelia, verify the cookie domain matches the protected host, and verify the proxy is not stripping the session cookie. None of this is Authelia-specific — it is the standard forward-auth integration tax — but it is the hill most newcomers must climb once.

10. Authelia as an OpenID Connect Provider

The March 2026 OIDC certification changed what Authelia can be. Beyond forward-auth, Authelia can now issue OIDC tokens to applications that natively support OIDC login. This means a service like Ghost or Umami (covered elsewhere in this series) that has an OIDC client can authenticate directly against Authelia, receiving a standards-compliant token rather than relying on proxy-injected headers. This matters because forward-auth headers are a blunt instrument: they tell the backend "this user is authenticated" but they do not give the app a rich, revocable, scope-limited token the way OIDC does. For apps that understand OIDC, the native flow is cleaner, supports single logout better, and aligns with how the broader identity ecosystem works. Authelia's dual nature — gate and OIDC provider — means you can mix both models in one stack: header-based protection for the legacy apps that only understand proxies, and OIDC for the modern ones that speak the standard. The honest caveat is that running Authelia as a full OIDC provider is more configuration than running it as a pure forward-auth gate. You define clients, redirect URIs, scopes, and signing keys. It is well within reach of someone who already runs the forward-auth setup, but it is a step up in surface area, and more surface area means more to get wrong. The recommendation is to start with forward-auth, get comfortable, then add OIDC clients as needed.

11. Authelia vs Keycloak and Authentik

Because we have covered both Keycloak and Authentik in this series, the natural question is when to pick the lightweight gate over the full IdP. The distinction is scope. Keycloak (Apache-2.0, Red Hat-maintained) is a complete identity and access management platform: it is where you manage a full user directory, federate with other IdPs via SAML or OIDC, run multi-tenancy, and issue tokens to third parties. If your requirement includes "our customer wants to log in with their Okta via SAML," Keycloak is the answer and Authelia is not. Authentik (also covered) sits in a similar full-platform space with a polished UI and its own open-core nuances. Authelia's argument is the inverse: if what you actually need is "one login and a second factor in front of a set of self-hosted apps I already run," it delivers that with a fraction of the operational weight. You are not standing up a JVM, you are not managing a directory schema, you are not reasoning about tenant isolation. You are dropping a small binary in front of your proxy and writing one policy file. For the homelab and the small-team edge case, that economy is the entire point. The decision rule we would give a self-hoster: if you need SAML, user federation, or multi-tenancy, go Keycloak or Authentik. If you need to put SSO and 2FA in front of apps that were never built for it, and you want to do it with minimal machinery, Authelia is the cleaner tool. Many mature stacks actually run both — Keycloak as the directory and OIDC source, Authelia as the forward-auth gate for the apps that only understand proxies — but that is a sophistication most people grow into rather than start with.

12. What It Costs to Run

The cost story for Authelia is mostly favorable, which is part of its appeal. Compute cost is negligible: a single Go binary measured in tens of megabytes of RAM and trivial CPU. You can run it on the same small host that runs your proxy. There is no license fee, no per-user cost, no telemetry that bills you. The real costs are indirect. First, Redis: if you follow best practice for anything beyond a toy deployment, you are now operating a Redis instance as auth-critical infrastructure, with its own backup and availability story. Second, the proxy integration tax: your time learning forward-auth for your specific proxy. Third, the opportunity cost of scope — because Authelia will not do SAML or federation, if you later discover you need those, you will be standing up Keycloak anyway, and Authelia becomes a partial solution. None of these are hidden; they are the normal costs of running a security boundary. But they are worth naming so you do not adopt Authelia expecting zero operational footprint. The binary is light; the system around it (proxy rules, Redis, policy files, backups) is the actual work.

13. Where Your Data Goes

A sovereign operator wants to know exactly what leaves their network. With Authelia, the data-flow map is reassuringly contained. Your user credentials and group mappings live in whatever backend you chose — a local file, SQLite, PostgreSQL, or your LDAP/AD server. None of that is sent to Authelia's developers or any third party. Session state lives in your Redis (or your database), on your infrastructure. The Authelia binary itself makes no outbound calls to function. The exceptions are the optional integrations. If you use Duo for push 2FA, Authelia calls the Duo API (a Cisco-operated service) during login — that is a deliberate outbound dependency you opt into. If you configure notifications (for example, new-device or breach alerts), those may go to an SMTP server or a webhook you specify. And if you point Authelia at an external LDAP/AD, authentication traffic naturally flows to that directory. None of these are covert; they are explicit, configurable, and only present if you enable them. For the privacy-minded, the cleanest configuration is file or database users with TOTP or WebAuthn (no Duo), Redis on the local network, and no external notifications. In that mode, Authelia is a fully self-contained auth gate with zero third-party data flow. That is about as sovereign as authentication infrastructure gets.

14. The Hard Scope Limits

No honest review skips the boundaries, and Authelia has deliberate ones. Understanding them is how you avoid adopting the wrong tool. No SAML. Authelia is an OIDC provider, not a SAML IdP. A SAML 2.0 IdP is on the roadmap but, as of mid-2026, remains in the planning stage. If a service or partner requires SAML, Authelia cannot be your IdP for that flow — you would bridge through something like Keycloak. No user federation. Authelia authenticates against the backend you point it at; it does not federate with external identity providers to combine directories. It is the front door to one directory, not a hub that merges many. No multi-tenancy. There is no built-in concept of isolating multiple organizations within one Authelia deployment. If you are a service provider hosting separate tenants, Authelia's model does not give you tenant boundaries; you would run separate instances or use a full IdP. It is a gate, not a directory. Authelia is not where you model your org. Managing users, groups, and lifecycle is the job of the backend (especially LDAP/AD). Authelia consumes that; it does not replace it. Lock-out risk. Because it sits in front of everything, a broken config or a down Redis can block access to your whole stack. This is the inherent risk of perimeter auth, and it is why backups and staged rollouts matter more here than for almost any other component you run. None of these are criticisms. They are scope. Authelia does a narrow job extremely well, and the discipline to not become a sprawling IdP is precisely why it stays light. But "narrow" means "know the edges before you commit."

15. Security Operations: Backups and Upgrades

Operating Authelia safely is mostly about respecting that it is auth-critical. The backup list is short but non-negotiable: your configuration.yml (the policy file), your user database or users_database.yml, and your Redis dump if sessions matter to you. Store these with the same care you give TLS private keys, because together they govern access to your stack. Upgrades follow the standard container pull-and-restart, and because Authelia maintains semantic versioning within the 4.x line, config compatibility is generally preserved. The discipline is to skim the release notes before upgrading anything security-critical — a same-week patch like v4.39.28 is safe to take immediately, but a feature release deserves a glance at the changelog for config-variable renames. And as always with the auth layer, test your login flow after upgrading: confirm that TOTP, WebAuthn, and Duo push all behave as expected before declaring the upgrade done. One more operational note: because Authelia is the gate, consider running it on infrastructure that is not solely dependent on the very services it protects. If Authelia's health check depends on a database that only Authelia can unlock, you have built a dependency loop. Keeping Authelia's own dependencies (Redis, its user DB) independent of the apps behind it is the difference between resilient and fragile.

16. Troubleshooting the Common Failures

The failure modes are predictable enough to enumerate. Infinite redirect loops almost always mean the proxy is not preserving the session cookie or the auth sub-request is not sharing the same cookie domain as the protected host. Fix the cookie domain and the loop collapses. "401 from the proxy even though I'm logged in" usually means the proxy is not forwarding the authelieved headers, or the auth sub-request path is wrong. Duo pushes that succeed but fail were a real bug (v4.39.18) — upgrade if you are on an affected version. Policy over-deny (locked out of a service) means a rule is matching where you did not expect; check rule order, since first-match-wins is unforgiving. Redis down forces re-auth or blocks validation; that is Redis's availability showing through. The general method is the same as any auth debugging: isolate the sub-request. Can the proxy reach Authelia's /api/verify? Does that endpoint see the session cookie? Does the response tell the proxy to allow? Walking that chain step by step resolves the vast majority of issues without guessing.

17. Frequently Asked Questions

Is Authelia a replacement for my app's own login? For apps behind the proxy, effectively yes — the gate handles authentication before the request arrives. The app may still have its own account, but it is now reached only by authenticated, authorized users. Do I need a reverse proxy? Yes. Authelia's model is forward-auth; without a proxy that supports it, there is no door to stand in front of. Can Authelia do SSO across completely unrelated domains? Within the policy file, yes — any host routed through the proxy and Authelia shares the same session. Across entirely separate Authelia deployments, no, unless you federate (which Authelia does not do natively). Is WebAuthn better than TOTP? For phishing resistance, yes. TOTP can be intercepted via phishing; WebAuthn binds to the origin and cannot be. Prefer WebAuthn where users have the hardware. Why Redis if it's a small tool? Because session state needs a shared, expiring store, especially for multi-instance or production use. For a single tiny deployment you can use the database backend, but Redis is the recommended path.

18. Who Should Run It, and Who Shouldn't

Authelia is for the operator who runs several self-hosted services and wants one login and a real second factor in front of all of them, without standing up a heavy identity platform. Homelabs, single-admin setups, and small teams with a directory (or willing to use a file/DB backend) are the sweet spot. It is also ideal as the forward-auth gate for apps that will never speak OIDC natively. It is not for you if you need SAML, identity federation, multi-tenancy, or a full user-lifecycle directory — those requirements point to Keycloak or Authentik. It is also not for the operator who wants a turnkey GUI that writes the config; Authelia is YAML-driven by design, and that is not changing. The right way to think about adoption is as a security boundary, not a feature checkbox. The question is not "does it have SAML" but "do I have a consistent, enforced front door for my stack?" If the answer is no and you run more than two protected services, Authelia is one of the cleanest ways to get one.

19. A Practical Hardening Checklist

If you take Authelia seriously as your security boundary, a short hardening checklist turns a working demo into a defensible deployment. Require 2FA for every protected subdomain rather than only the admin ones — the floor only matters if it applies everywhere. Prefer WebAuthn over TOTP wherever users have the hardware, because phishing is the dominant real-world credential threat and WebAuthn is the factor designed to defeat it. Store credentials in PostgreSQL rather than a hand-edited users file once you have more than two accounts, so changes do not require restarts and password hashes are not sitting in a config-volume file. Back up configuration.yml and the user store before every upgrade, and keep the previous image tag so you can roll back a bad release in minutes. Run Authelia's Redis and database on infrastructure that does not itself depend on the apps behind the gate, so an auth outage cannot cascade into a dependency loop. Finally, test policy changes against a throwaway subdomain before applying them to production routes — first-match-wins rules reward caution. None of this is exotic; it is the standard discipline of treating authentication as the most important thing you run.

20. Where Your Data Goes (Revisited)

To close the loop on sovereignty: Authelia, in its default and recommended configuration, keeps all credentials, sessions, and policies on infrastructure you control. The only outbound data flows are the ones you explicitly enable — Duo pushes, SMTP notifications, or an external LDAP directory. Strip those out and you have an authentication gate with no third-party dependencies and no telemetry. For a self-hoster who has just spent the effort to self-host everything else, that containment is the entire value proposition: you finally have one consistent, enforced, self-owned front door.

Related

For the rest of a sovereign, self-hosted stack, these pieces from our series travel with Authelia:

Comments (0)

No comments yet. Be the first to comment!

Leave a Comment