---
title: Forward auth
---

Using forward auth uses your existing reverse proxy to do the proxying, and only uses the
authentik outpost to check authentication and authorization.

To use forward auth instead of proxying, you have to change a couple of settings.
In the Proxy Provider, make sure to use one of the Forward auth modes.

## Single application

Single application mode works for a single application hosted on its dedicated subdomain. This
has the advantage that you can still do per-application access policies in authentik.

## Domain level

To use forward auth instead of proxying, you have to change a couple of settings.
In the Proxy Provider, make sure to use the *Forward auth (domain level)* mode.

This mode differs from the *Forward auth (single application)* mode in the following points:
- You don't have to configure an application in authentik for each domain
- Users don't have to authorize multiple times

There are however also some downsides, mainly the fact that you **can't** restrict individual
applications to different users.

The only configuration difference between single application and domain level is the host you specify.

For single application, you'd use the domain which the application is running on, and only /akprox
is redirected to the outpost.

For domain level, you'd use the same domain as authentik.

:::info
*example-outpost* is used as a placeholder for the outpost name.
*authentik.company* is used as a placeholder for the authentik install.
:::

## Nginx

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

<Tabs
  defaultValue="standalone-nginx"
  values={[
    {label: 'Standalone nginx', value: 'standalone-nginx'},
    {label: 'Ingress', value: 'ingress'},
  ]}>
  <TabItem value="standalone-nginx">

```
server {
    # SSL and VHost configuration
    listen                  443 ssl http2;
    server_name             _;

    ssl_certificate         /etc/ssl/certs/ssl-cert-snakeoil.pem;
    ssl_certificate_key     /etc/ssl/private/ssl-cert-snakeoil.key;

    # Increase buffer size for large headers
    # This is needed only if you get 'upstream sent too big header while reading response header from upstream' error when trying to access an application protected by goauthentik
    proxy_buffers 8 16k;
    proxy_buffer_size 32k;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;

    location / {
        # Put your proxy_pass to your application here
        # proxy_pass          http://localhost:5000;

        # authentik-specific config
        auth_request        /akprox/auth/nginx;
        error_page          401 = @akprox_signin;
        # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
        # error_page          401 =302 https://authentik.company/akprox/start?rd=$scheme://$http_host$request_uri;

        # translate headers from the outposts back to the actual upstream
        auth_request_set    $username    $upstream_http_x_auth_username;
        auth_request_set    $email       $upstream_http_X_Forwarded_Email;
        proxy_set_header    X-Auth-Username   $username;
        proxy_set_header    X-Forwarded-Email $email;
    }

    # all requests to /akprox must be accessible without authentication
    location /akprox {
        proxy_pass          http://*ip or hostname of the authentik OUTPOST*:9000/akprox;
        # ensure the host of this vserver matches your external URL you've configured
        # in authentik
        proxy_set_header    Host $host;
        add_header          Set-Cookie $auth_cookie;
        auth_request_set    $auth_cookie $upstream_http_set_cookie;
    }

    # Special location for when the /auth endpoint returns a 401,
    # redirect to the /start URL which initiates SSO
    location @akprox_signin {
        internal;
        add_header Set-Cookie $auth_cookie;
        return 302 /akprox/start?rd=$request_uri;
    }
}
```

  </TabItem>
  <TabItem value="ingress">
Create a new ingress for the outpost

```yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: authentik-outpost
spec:
  rules:
  - host: *external host that you configured in authentik*
    http:
      paths:
      - backend:
          serviceName: authentik-outpost-example-outpost
          servicePort: 9000
        path: /akprox
```

This ingress handles authentication requests, and the sign-in flow.

Add these annotations to the ingress you want to protect

```yaml
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-url: https://*external host that you configured in authentik*/akprox/auth?nginx
    nginx.ingress.kubernetes.io/auth-signin: https://*external host that you configured in authentik*/akprox/start?rd=$escaped_request_uri
    nginx.ingress.kubernetes.io/auth-response-headers: X-Auth-Username,X-Forwarded-Email,X-Forwarded-Preferred-Username,X-Forwarded-User,X-Auth-Groups
    nginx.ingress.kubernetes.io/auth-snippet: |
       proxy_set_header X-Forwarded-Host $http_host;
```
  </TabItem>
</Tabs>

## Traefik

<Tabs
  defaultValue="standalone-traefik"
  values={[
    {label: 'Standalone traefik', value: 'standalone-traefik'},
    {label: 'docker-compose', value: 'docker-compose'},
    {label: 'Ingress', value: 'ingress'},
  ]}>
  <TabItem value="standalone-traefik">

```yaml
http:
  middlewares:
    authentik:
      forwardAuth:
        address: http://authentik-outpost-example-outpost:9000/akprox/auth/traefik
        trustForwardHeader: true
        authResponseHeaders:
          - Set-Cookie
          - X-Auth-Username
          - X-Auth-Groups
          - X-Forwarded-Email
          - X-Forwarded-Preferred-Username
          - X-Forwarded-User
  routers:
    default-router:
      rule: "Host(`*external host that you configured in authentik*`)"
      middlewares:
        - name: authentik
      priority: 10
      services: # Unchanged
    default-router-auth
      match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)"
      priority: 15
      services: http://*ip of your outpost*:9000/akprox
```
  </TabItem>
  <TabItem value="docker-compose">

```yaml
version: '3.7'
services:
  traefik:
    image: traefik:v2.2
    container_name: traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      traefik.enable: true
      traefik.http.routers.api.rule: Host(`traefik.example.com`)
      traefik.http.routers.api.entrypoints: https
      traefik.http.routers.api.service: api@internal
      traefik.http.routers.api.tls: true
    ports:
      - 80:80
      - 443:443
    command:
      - '--api'
      - '--log=true'
      - '--log.level=DEBUG'
      - '--log.filepath=/var/log/traefik.log'
      - '--providers.docker=true'
      - '--providers.docker.exposedByDefault=false'
      - '--entrypoints.http=true'
      - '--entrypoints.http.address=:80'
      - '--entrypoints.http.http.redirections.entrypoint.to=https'
      - '--entrypoints.http.http.redirections.entrypoint.scheme=https'
      - '--entrypoints.https=true'
      - '--entrypoints.https.address=:443'

  authentik_proxy:
    image: goauthentik.io/proxy:2021.5.1
    ports:
      - 9000:9000
      - 9443:9443
    environment:
      AUTHENTIK_HOST: https://your-authentik.tld
      AUTHENTIK_INSECURE: "false"
      AUTHENTIK_TOKEN: token-generated-by-authentik
      # Starting with 2021.9, you can optionally set this too
      # when authentik_host for internal communication doesn't match the public URL
      # AUTHENTIK_HOST_BROWSER: https://external-domain.tld
    labels:
      traefik.enable: true
      traefik.port: 9000
      traefik.http.routers.authentik.rule: Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)
      traefik.http.routers.authentik.entrypoints: https
      traefik.http.routers.authentik.tls: true
      traefik.http.middlewares.authentik.forwardauth.address: http://authentik_proxy:9000/akprox/auth/traefik
      traefik.http.middlewares.authentik.forwardauth.trustForwardHeader: true
      traefik.http.middlewares.authentik.forwardauth.authResponseHeaders: Set-Cookie,X-Auth-Username,X-Auth-Groups,X-Forwarded-Email,X-Forwarded-Preferred-Username,X-Forwarded-User
    restart: unless-stopped

  whoami:
    image: containous/whoami
    labels:
      traefik.enable: true
      traefik.http.routers.whoami.rule: Host(`*external host that you configured in authentik*`)
      traefik.http.routers.whoami.entrypoints: https
      traefik.http.routers.whoami.tls: true
      traefik.http.routers.whoami.middlewares: authentik@docker
    restart: unless-stopped
```

  </TabItem>
  <TabItem value="ingress">
Create a middleware:

```yaml
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: authentik
spec:
  forwardAuth:
    address: http://authentik-outpost-example-outpost:9000/akprox/auth/traefik
    trustForwardHeader: true
    authResponseHeaders:
      - Set-Cookie
      - X-Auth-Username
      - X-Auth-Groups
      - X-Forwarded-Email
      - X-Forwarded-Preferred-Username
      - X-Forwarded-User
```

Add the following settings to your IngressRoute

:::warning
By default traefik does not allow cross-namespace references for middlewares:

See [here](https://doc.traefik.io/traefik/v2.4/providers/kubernetes-crd/#allowcrossnamespace) to enable it.
:::

```yaml
spec:
  routes:
    - kind: Rule
      match: "Host(`*external host that you configured in authentik*`)"
      middlewares:
        - name: authentik
          namespace: authentik
      priority: 10
      services: # Unchanged
    # This part is only required for single-app setups
    - kind: Rule
      match: "Host(`*external host that you configured in authentik*`) && PathPrefix(`/akprox/`)"
      priority: 15
      services:
        - kind: Service
          name: authentik-outpost-example-outpost
          port: 9000
```
  </TabItem>
</Tabs>