Protect Webtop Behind Nginx Proxy Manager With Authentik (Forward Auth)

[Note. I had to update authentik to get this to work. was prev running 2025.8.3 and everything I tried didnt resolve]

This guide shows a working setup for protecting webtop.tekonline.com.au (LinuxServer Webtop) behind Nginx Proxy Manager (NPM) using Authentik forward-auth.

Tested on February 4, 2026 with Authentik 2025.10.3 (embedded outpost path /outpost.goauthentik.io).

Prerequisites

  • Authentik already installed and reachable (you can log into the Authentik admin UI).
  • Nginx Proxy Manager already installed and serving public HTTPS for your domain.
  • DNS record for your app (example: webtop.tekonline.com.au) pointing to NPM.
  • Your protected app is reachable from the NPM container.
    • If using Docker, put NPM + Authentik + the app on the same Docker network, and use container names (example: authentik-serverdev-webtop).

1) Run Webtop (Example)

If you’re running LinuxServer Webtop as a container on the same host, it’s typically reachable internally on port 3000. For NPM, the key is:

  • NPM must be able to reach the upstream by name/IP (example: dev-webtop:3000).
  • You do not need to publish Webtop’s port to the internet if NPM proxies to it over the Docker network.

2) Authentik Config (Provider + Application)

In Authentik Admin:

2.1 Create (or reuse) an Application

  • Name: Webtop
  • Slug: webtop (any value)
  • Launch URL: https://webtop.tekonline.com.au/

2.2 Create a Proxy Provider (Forward Auth)

Create a Provider of type Proxy Provider:

  • Name: webtop-provider
  • Mode: Forward auth (single application)
  • External host: https://webtop.tekonline.com.au
  • Authorization flow: choose your existing default flow (or create one)
  • Cookie domain: usually leave default unless you need cross-subdomain SSO
  • Optional: enable “Send HTTP Basic authentication” only if your upstream needs it

Attach the Provider to the Application.

2.3 Embedded Outpost

This guide uses the embedded outpost at:

  • /outpost.goauthentik.io

Your reverse proxy (NPM) must allow /outpost.goauthentik.io/* without requiring authentication (we do that in the Nginx snippet below).


3) NPM Config (Proxy Host + SSL)

In NPM:

3.1 Create a Proxy Host

Create a Proxy Host for webtop.tekonline.com.au:

  • Forward hostname: dev-webtop (or your upstream IP/container name)
  • Forward port: 3000
  • Scheme: http

3.2 SSL

  • Request/assign a Let’s Encrypt cert for webtop.tekonline.com.au
  • Enable Force SSL

Force SSL is important for SSO flows because cookies are often marked Secure and will not be sent over HTTP.

3.3 Advanced

Paste the Nginx config in the next section into the Advanced tab.


4) NPM “Advanced” Nginx Snippet (Working)

Paste this into the NPM proxy host Advanced tab.

Notes:

  • Ensure authentik-server:9000 matches your Authentik container/service name and port.
  • Your actual upstream app target is defined by the NPM UI and used here via $forward_scheme://$server:$port.
# NPM Advanced tab: Authentik forward-auth for webtop.tekonline.com.au

# Increase buffer size for large headers (helps avoid "upstream sent too big header" with SSO cookies)
proxy_buffers 8 16k;
proxy_buffer_size 32k;

# Make sure not to redirect traffic to a port 4443
port_in_redirect off;

location / {
    # Preserve the original URL for the auth subrequest (auth_request uses an internal location below).
    set $ak_orig_url https://$http_host$request_uri;

    # Proxy to your application (set in the NPM UI: $forward_scheme://$server:$port)
    proxy_pass          $forward_scheme://$server:$port;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $forward_scheme;

    # Websockets support (Webtop needs this)
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $http_connection;
    proxy_http_version 1.1;

    proxy_read_timeout 86400;

    ##############################
    # authentik-specific config
    ##############################
    # Run forward-auth against Authentik via an internal location.
    # This avoids NPM encoding `?rd=` into `%3F`, which can break the auth request path.
    auth_request     /__ak_auth;
    error_page       401 = @goauthentik_proxy_signin;

    auth_request_set $auth_cookie $upstream_http_set_cookie;
    add_header       Set-Cookie $auth_cookie;

    auth_request_set $authentik_username $upstream_http_x_authentik_username;
    auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
    auth_request_set $authentik_entitlements $upstream_http_x_authentik_entitlements;
    auth_request_set $authentik_email $upstream_http_x_authentik_email;
    auth_request_set $authentik_name $upstream_http_x_authentik_name;
    auth_request_set $authentik_uid $upstream_http_x_authentik_uid;

    proxy_set_header X-authentik-username $authentik_username;
    proxy_set_header X-authentik-groups $authentik_groups;
    proxy_set_header X-authentik-entitlements $authentik_entitlements;
    proxy_set_header X-authentik-email $authentik_email;
    proxy_set_header X-authentik-name $authentik_name;
    proxy_set_header X-authentik-uid $authentik_uid;

    # If you enabled “Send HTTP Basic authentication” in the provider, uncomment:
    # auth_request_set $authentik_auth $upstream_http_authorization;
    # proxy_set_header Authorization $authentik_auth;
}

# Internal auth subrequest. Uses the original URL captured in `location /`.
location = /__ak_auth {
    internal;
    proxy_pass              http://authentik-server:9000/outpost.goauthentik.io/auth/nginx;
    proxy_set_header        Host $http_host;
    proxy_set_header        X-Original-URL $ak_orig_url;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto https;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
}

# All requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
    proxy_pass              http://authentik-server:9000/outpost.goauthentik.io;

    # Ensure Host is the protected app host (must match the provider's external_host)
    proxy_set_header        Host $http_host;

    proxy_set_header        X-Original-URL https://$http_host$request_uri;
    add_header              Set-Cookie $auth_cookie;
    auth_request_set        $auth_cookie $upstream_http_set_cookie;

    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
}

# If the /auth endpoint returns a 401, redirect to the /start URL which initiates SSO
location @goauthentik_proxy_signin {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 /outpost.goauthentik.io/start?rd=https://$http_host$request_uri;
}

5) Quick Verification

  1. Visit:
  • https://webtop.tekonline.com.au/
  1. Expected behavior:
  • You’re redirected to /outpost.goauthentik.io/start?...
  • You log into Authentik
  • You’re redirected back to Webtop and the UI loads

Troubleshooting

400 Bad Request on callback (or “state”/cookie problems)

  • Make sure Force SSL is enabled in NPM for the proxy host.
  • If the first request is HTTP, the browser may not send Secure cookies and the SSO flow breaks.

504 Gateway Timeout after login

This nearly always means NPM can’t reach your upstream app.

Check:

  • NPM Proxy Host “Details”: Forward Hostname/IP is correct (example: dev-webtop)
  • Port is correct (3000)
  • Containers share a Docker network (if using container names)

auth_request unexpected status: 404 in NPM logs

This typically means NPM is hitting the wrong outpost path/host or the outpost isn’t being proxied correctly.

Fix:

  • Ensure /outpost.goauthentik.io is proxied to http://authentik-server:9000/outpost.goauthentik.io
  • Ensure proxy_set_header Host $http_host; is present for that location

Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *