Currently Available: Need a skilled Software Developer for your next project?
Categories
Self-Hosting

How to Set Up Authentik Forward Auth With Nginx Proxy Manager Without Internal-IP Redirects

When you use Nginx Proxy Manager (NPM) and Authentik to protect a website, NPM asks Authentik to check each request before it reaches the website. This check is called forward authentication. Authentik tells NPM whether the visitor is signed in, and NPM either lets the request through or sends the visitor to sign in.

NPM may contact Authentik’s outpost, the component that handles these sign-in checks, through an internal hostname or IP address. The browser’s sign-in and return URLs should use the website’s public hostname and URL scheme (HTTP or HTTPS), such as https://app.example.com.

Set Authentik’s public URL to the website’s full public URL, then use NPM’s documented forward-auth locations. This keeps internal addresses out of redirects. If a redirect still contains an internal IP, check its Location header to find which service sent the browser there.

Configure Authentik for the public website

In Authentik, create an application and a Proxy Provider. Choose Forward auth (single application) when you want a separate provider and access rules for this website. Set the provider’s External host to the complete public URL, including https:// and any nonstandard port. Then assign the application to an outpost, such as Authentik’s embedded outpost.

In single-application mode, Authentik sends this website’s sign-in checks to its own provider. Authentik also supports domain-level forward auth, which covers multiple websites under one parent domain. That mode cannot apply a separate authorization policy to each protected website. See Authentik’s documentation on forward-auth modes and creating a proxy provider.

Route NPM’s auth checks to the outpost

In NPM, create or edit the proxy host for the public website. In its Advanced tab, add the outpost location and the named sign-in location from Authentik’s NPM configuration example. The outpost’s proxy_pass should use an internal address that NPM can reach. For example, http://authentik.internal:9000 is a placeholder; use the address and port that match your network and outpost.

The proxy_pass address tells NPM how to reach Authentik. It does not set the hostname in the browser’s redirect. The sign-in location should build the return URL from the incoming request’s scheme (HTTP or HTTPS) and host (the public hostname). Authentik’s example uses this redirect:

return 302 /outpost.goauthentik.io/start?rd=$scheme://$ak_http_host$request_uri;

The relative path keeps the sign-in request on the public website’s host. The $scheme and $ak_http_host variables supply the original request’s scheme and host; Authentik’s example also falls back from $http_host to $host if $http_host is empty.

Adding a location / block in NPM’s Advanced tab replaces the location NPM generated, including its Access List rules. Instead, create a / Custom Location and match the proxy host’s scheme. Set the upstream hostname or IP and port to match the proxy host. Open the location’s gear menu and add the authentication directives there. Do not add a location wrapper or another proxy_pass in the gear-menu configuration.

Add the forward-auth check to the Custom Location

Add the core auth-check directives to the / Custom Location’s gear-menu configuration:

auth_request /outpost.goauthentik.io/auth/nginx;
error_page 401 = @goauthentik_proxy_signin;

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

The outpost location in the Advanced tab must route /outpost.goauthentik.io to the outpost and pass the original request information as shown in Authentik’s NPM example. That location also disables forwarding the request body during the auth check. Use the example’s relevant directives and adapt its upstream address to your network.

Authentik’s example also passes identity headers, including username, groups, email, name, and UID, to the application upstream. Include those headers when the application uses them. They carry user information; they do not set the browser’s redirect hostname. Enable WebSockets Support in NPM when the protected website requires WebSockets. If you also use NPM Access Lists, check Authentik’s instructions for how the Custom Location should inherit and enforce those rules.

Find which service created an internal-IP redirect

Check the browser’s network requests and the Location response header for each redirect. This header gives the address the browser was told to visit.

If the first redirect goes from the protected website to Authentik, check that the return target uses the public website host and scheme. If Authentik sends the browser back to an internal address, check the provider’s External host and the host and scheme headers that reach Authentik.

If the browser returns to the website and then gets redirected to an internal IP, the website may be starting its own sign-in flow, such as an OpenID Connect (OIDC) login. Check that website’s public or base URL and its reverse-proxy settings. Forward auth and an application’s own OIDC login are separate stages; a redirect created by the application requires investigation in that application’s configuration. A reported Mealie case describes this sequence, but it does not establish a general cause or fix.

A reverse proxy in front of Authentik must pass the original host and scheme in Host or X-Forwarded-Host and X-Forwarded-Proto. Authentik uses forwarded headers only when they come from a trusted proxy address. If Authentik does not trust the proxy that connects to it, it ignores those headers and can build URLs with the wrong host or scheme. Check Authentik’s reverse-proxy requirements and use trace-level outpost logs to see which headers reach Authentik.

You can also test whether the outpost route responds at the website’s public URL:

curl -v https://app.example.com/outpost.goauthentik.io/ping

Replace app.example.com with the protected website’s public hostname. Authentik says the expected response is HTTP 204. If you get a different response, check that NPM sends this path to the right outpost and can reach it. See Authentik’s forward-auth troubleshooting steps.

Patch the nginx forward-auth security issue

Authentik disclosed a critical vulnerability in nginx forward-auth mode involving a client-supplied X-Original-URI header. Its advisory lists Authentik versions through 2025.12.4 and 2026.2.2 as affected and names 2025.12.5 and 2026.2.3 as patched versions. Upgrade to a patched release or a later release that includes the fix. The security advisory rates the issue CVSS 3.1 10.0.

If you cannot upgrade now, follow the advisory’s workaround at the nginx layer: clear X-Original-URI in the location that sends requests to the outpost. For example:

proxy_set_header X-Original-URI "";

Clearing X-Original-URI leaves the normal forward-auth configuration in place. This header is separate from X-Original-URL, which Authentik’s NPM example uses to pass the original request URL.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

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