Back to articles
Technology Insight

Self-Hosting Authentik with YubiKey (FIDO2) as a Secure WAF Gateway for All Docker Applications on a VPS

June 3, 2026

Introduction: The Growing Need for Centralized Perimeter Security

In the modern era of self-hosting, deploying applications via Docker on a Virtual Private Server (VPS) has become the standard for businesses and independent developers alike. From project management tools like OpenProject to internal dashboards and databases, the convenience of containerization is undeniable. However, this convenience introduces a significant security challenge: exposing multiple individual applications to the public internet creates an expanded attack surface.

Relying on the built-in, often rudimentary authentication mechanisms of separate apps leaves your infrastructure vulnerable to credential stuffing, brute-force attacks, and unpatched zero-day exploits. To mitigate this risk, enterprise-grade architecture dictates the use of a centralized identity provider (IdP) acting as a security gateway or Web Application Firewall (WAF) layer before traffic ever reaches your backend services. This technical guide explores how to self-host Authentik and integrate it with YubiKey (FIDO2/WebAuthn) to establish an ironclad, zero-trust perimeter for your entire Docker-based VPS infrastructure.

Why Authentik and YubiKey (FIDO2)?

Before diving into the implementation, it is critical to understand why this specific combination offers superior protection compared to traditional setups:

  • Authentik: An open-source, highly versatile Identity Provider that excels at unifying authentication. It can act as a forward auth proxy for reverse proxies (like Traefik, Nginx Proxy Manager, or Caddy), effectively shielding unauthorized traffic at the network edge.
  • YubiKey (FIDO2): Hardware-based authentication represents the gold standard of Multi-Factor Authentication (MFA). Unlike SMS codes or Time-based One-Time Passwords (TOTP), FIDO2/WebAuthn is inherently immune to phishing, man-in-the-middle (MITM) attacks, and SIM-swapping, as the cryptographic handshake is bound strictly to the specific domain.

By combining these two technologies, you create a unified entry point where users must present a physical hardware token before accessing any internal application. If an attacker cannot bypass Authentik, they cannot even attempt to exploit the login page of your underlying applications.

Architecture Overview

To implement this setup efficiently, we utilize a reverse proxy as the traffic coordinator alongside Authentik. The standard request lifecycle follows this pipeline:

  1. An external user requests access to an application (e.g., app.yourdomain.com).
  2. The Reverse Proxy (such as Traefik or Nginx Proxy Manager) intercepts the request and forwards it to Authentik via a Forward Auth middleware.
  3. Authentik checks the session. If unauthenticated, it presents the login portal demanding username/password and the physical YubiKey.
  4. Once FIDO2 authentication succeeds, Authentik returns a valid session cookie to the proxy.
  5. The Reverse Proxy grants passage and forwards the clean traffic to the target Docker container.
Security Note: Because Authentik handles the perimeter validation, your individual applications do not even need to be exposed to the public internet directly via host ports; they can remain entirely within an isolated Docker internal network.

Step-by-Step Deployment Guide

1. Prerequisites and VPS Initialization

Ensure your VPS is running a clean installation of a modern Linux distribution (e.g., Ubuntu 24.04 LTS or Debian 12). You will need a registered domain name with wildcard DNS capabilities (e.g., pointing *.yourdomain.com and yourdomain.com to your VPS public IP address). Install Docker and the Docker Compose plugin using the official repositories:

sudo apt update && sudo apt install -y curl ufw
curl -fsSL [https://get.docker.com](https://get.docker.com) -o get-docker.sh
sudo sh get-docker.sh

Configure your system firewall to only allow essential traffic: SSH (port 22), HTTP (port 80), and HTTPS (port 443).

2. Deploying Authentik via Docker Compose

Create a dedicated directory for Authentik and download the official compose and environment files. Authentik relies on a PostgreSQL database for state storage and a Redis instance for caching and asynchronous tasks.

mkdir -p ~/authentik && cd ~/authentik
wget [https://goauthentik.io/docker-compose.yml](https://goauthentik.io/docker-compose.yml)
wget -O .env [https://goauthentik.io/contrib/env.env](https://goauthentik.io/contrib/env.env)

Open the .env file to generate secure credentials and define your external domain. It is vital to use strong, randomly generated keys for production environments:

echo "AUTHENTIK_SECRET_KEY=$(openssl rand -urandom 50 | base64 | tr -d '\n')" >> .env
echo "AUTHENTIK_PG_PASS=$(openssl rand -urandom 30 | base64 | tr -d '\n')" >> .env

Launch the containers in detached mode:

docker compose up -d

Navigate to http://:9000/if/flow/initial-setup/ to initialize the administrator account. Follow the prompts to set up your primary admin email and password.

3. Configuring YubiKey (FIDO2/WebAuthn) in Authentik

Once logged into the Authentik Admin Interface, follow these steps to enforce phishing-resistant MFA:

  • Navigate to System -> Flows & Stages.
  • Click on Stages and create a new WebAuthn Device Authenticator Stage. Name it clearly (e.g., yubikey-fido2-stage). Configure the Relying Party ID to match your top-level domain (e.g., yourdomain.com).
  • Go to Flows and locate your default authentication flow (typically default-authentication-flow).
  • Edit the bindings of the flow to insert your WebAuthn stage immediately after the standard identification step. This ensures that after providing credentials, the user is systematically prompted to touch their YubiKey.

To register your physical key, go to your User Settings page within the Authentik interface, select MFA Devices, click Register Device, choose WebAuthn/FIDO2, and physically touch your YubiKey when prompted by your browser. Ensure your browser supports WebAuthn APIs (Chrome, Firefox, Safari, and Edge support this natively).

4. Implementing Forward Auth for Docker Applications

To use Authentik as a protective shield for other Docker containers, configure an Authentik Provider and an Outpost. Under the Admin interface, navigate to Applications -> Providers and create a provider of type Proxy Provider. Set the external host to match your application URL (e.g., app.yourdomain.com).

Next, bind this Provider to an Application entry within Authentik. If you are using Traefik as your primary reverse proxy, add the following configuration labels to your application's docker-compose.yml block to trigger the Authentik middleware validation:

labels:
  - "traefik.http.routers.myapp.middlewares=authentik@docker"
  - "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik"
  - "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true"
  - "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-Authentik-Username,X-Authentik-Groups,X-Authentik-Email"

This explicit configuration forces the reverse proxy to pause every incoming request, check validation status with Authentik via local network speeds, and only pass the traffic forward if a valid, YubiKey-verified session cookie exists.

Best Practices for Production Environments

Operating a centralized authentication system introduces a single point of failure. If misconfigured, you could lock yourself out of your infrastructure. Implement the following resilience guidelines:

  • Emergency Break-Glass Accounts: Create a highly secure, isolated administrator account that bypasses WebAuthn, utilizing a long, split-key passphrase stored in separate physical safes. Use this only if you lose your physical hardware tokens.
  • Automated Backups: Schedule daily cron jobs to back up the PostgreSQL database volume and the Authentik configuration files. Store these backups encrypted on an off-site cloud bucket.
  • HTTP Strict Transport Security (HSTS): Enforce HSTS headers at the reverse proxy level to ensure that browsers never attempt to connect to Authentik or your protected applications via unencrypted HTTP.

Conclusion

By implementing Authentik as a forward-authenticating security gateway backed by YubiKey hardware tokens, you establish a world-class security posture for your self-hosted infrastructure. This defense-in-depth approach shields vulnerable Docker applications behind a unified, cryptographic firewall, neutralising the vast majority of automated external threats before they can reach your code. While the initial configuration requires technical precision, the peace of mind knowing your data is secured by un-phishable hardware MFA is well worth the investment.

Self-Hosting Authentik with YubiKey (FIDO2) as a Secure WAF Gateway for All Docker Applications on a VPS | DPTCloud