forward_auth (Caddyfile directive) - Caddy Documentation (original) (raw)

An opinionated directive which proxies a clone of the request to an authentication gateway, which can decide whether handling should continue, or needs to be sent to a login page.

Caddy's reverse_proxy is capable of performing "pre-check requests" to an external service, but this directive is tailored specifically for the authentication use case. This directive is actually just a convenient way to use a longer, more common configuration (below).

This directive makes a GET request to the configured upstream with the uri rewritten:

If this behaviour is not exactly what you want, you may take the expanded form below as a basis and customize it to your needs.

All the subdirectives of reverse_proxy are supported, and passed through to the underlying reverse_proxy handler.

Syntax

forward_auth [<matcher>] [<upstreams...>] {
    uri          <to>
    copy_headers <fields...> {
        <fields...>
    }
}

Since this directive is an opinionated wrapper over a reverse proxy, you can use any of reverse_proxy's subdirectives to customize it.

Expanded form

The forward_auth directive is the same as the following configuration. Auth gateways like Authelia work well with this preset. If yours does not, feel free to borrow from this and customize it as needed instead of using the forward_auth shortcut.

reverse_proxy <upstreams...> {
    # Always GET, so that the incoming
    # request's body is not consumed
    method GET

    # Change the URI to the auth gateway's
    # verification endpoint
    rewrite <to>

    # Forward the original method and URI,
    # since they get rewritten above; this
    # is in addition to other X-Forwarded-*
    # headers already set by reverse_proxy
    header_up X-Forwarded-Method {method}
    header_up X-Forwarded-Uri {uri}

    # On a successful response, copy response headers
    @good status 2xx
    handle_response @good {
        # for example, for each copy_headers field...
        request_header Remote-User {rp.header.Remote-User}
        request_header Remote-Email {rp.header.Remote-Email}
    }
}

Examples

Authelia

Delegating authentication to Authelia, before serving your app via a reverse proxy:

# Serve the authentication gateway itself
auth.example.com {
    reverse_proxy authelia:9091
}

# Serve your app
app1.example.com {
    forward_auth authelia:9091 {
        uri /api/authz/forward-auth
        copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
    }

    reverse_proxy app1:8080
}

For more information, see Authelia's documentation for integrating with Caddy.

Tailscale

Delegating authentication to Tailscale (currently named nginx-auth, but it still works with Caddy), and using the alternative syntax for copy_headers to rename the copied headers (note the > in each header):

forward_auth unix//run/tailscale.nginx-auth.sock {
    uri /auth
    header_up Remote-Addr {remote_host}
    header_up Remote-Port {remote_port}
    header_up Original-URI {uri}
    copy_headers {
        Tailscale-User>X-Webauth-User
        Tailscale-Name>X-Webauth-Name
        Tailscale-Login>X-Webauth-Login
        Tailscale-Tailnet>X-Webauth-Tailnet
        Tailscale-Profile-Picture>X-Webauth-Profile-Picture
    }
}