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 /outpost.goauthentik.io 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. app.company is used as a placeholder for the external domain for the application. outpost.company is used as a placeholder for the outpost. When using the embedded outpost, this can be the same as authentik.company
Nginx
- Standalone nginx
- Ingress
- Nginx Proxy Manager
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;
    location / {
        # Put your proxy_pass to your application here
        # proxy_pass          http://localhost:5000;
        # authentik-specific config
        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;
        # translate headers from the outposts back to the actual upstream
        auth_request_set $authentik_username $upstream_http_x_authentik_username;
        auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
        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-email $authentik_email;
        proxy_set_header X-authentik-name $authentik_name;
        proxy_set_header X-authentik-uid $authentik_uid;
    }
    # all requests to /outpost.goauthentik.io must be accessible without authentication
    location /outpost.goauthentik.io {
        proxy_pass          http://outpost.company:9000/outpost.goauthentik.io;
        # ensure the host of this vserver matches your external URL you've configured
        # in authentik
        proxy_set_header    Host $host;
        proxy_set_header    X-Original-URL $scheme://$http_host$request_uri;
        add_header          Set-Cookie $auth_cookie;
        auth_request_set    $auth_cookie $upstream_http_set_cookie;
        # required for POST requests to work
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
    }
    # Special location for when 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=$request_uri;
        # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
        # return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
    }
}
Create a new ingress for the outpost
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
    name: authentik-outpost
spec:
    rules:
        - host: app.company
          http:
              paths:
                  - backend:
                        # Or, to use an external Outpost, create an ExternalName service and reference that here.
                        # See https://kubernetes.io/docs/concepts/services-networking/service/#externalname
                        serviceName: ak-outpost-example-outpost
                        servicePort: 9000
                    path: /outpost.goauthentik.io
This ingress handles authentication requests, and the sign-in flow.
Add these annotations to the ingress you want to protect
metadata:
    annotations:
        nginx.ingress.kubernetes.io/auth-url: |-
            http://outpost.company:9000/outpost.goauthentik.io/auth/nginx
        # If you're using domain-level auth, use the authentication URL instead of the application URL
        nginx.ingress.kubernetes.io/auth-signin: |-
            https://app.company/outpost.goauthentik.io/start?rd=$escaped_request_uri
        nginx.ingress.kubernetes.io/auth-response-headers: |-
            Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid
        nginx.ingress.kubernetes.io/auth-snippet: |
            proxy_set_header X-Forwarded-Host $http_host;
For Nginx Proxy Manager you can use this snippet
# 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;
location / {
    # Put your proxy_pass to your application here
    proxy_pass          $forward_scheme://$server:$port;
    # authentik-specific config
    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;
    # translate headers from the outposts back to the actual upstream
    auth_request_set $authentik_username $upstream_http_x_authentik_username;
    auth_request_set $authentik_groups $upstream_http_x_authentik_groups;
    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-email $authentik_email;
    proxy_set_header X-authentik-name $authentik_name;
    proxy_set_header X-authentik-uid $authentik_uid;
}
# all requests to /outpost.goauthentik.io must be accessible without authentication
location /outpost.goauthentik.io {
    proxy_pass          http://outpost.company:9000/outpost.goauthentik.io;
    # ensure the host of this vserver matches your external URL you've configured
    # in authentik
    proxy_set_header    Host $host;
    proxy_set_header    X-Original-URL $scheme://$http_host$request_uri;
    add_header          Set-Cookie $auth_cookie;
    auth_request_set    $auth_cookie $upstream_http_set_cookie;
    # required for POST requests to work
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
}
# Special location for when 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=$request_uri;
    # For domain level, use the below error_page to redirect to your authentik server with the full redirect path
    # return 302 https://authentik.company/outpost.goauthentik.io/start?rd=$scheme://$http_host$request_uri;
}
Traefik
- Standalone traefik
- docker-compose
- Ingress
http:
    middlewares:
        authentik:
            forwardAuth:
                address: http://outpost.company:9000/outpost.goauthentik.io/auth/traefik
                trustForwardHeader: true
                authResponseHeaders:
                    - X-authentik-username
                    - X-authentik-groups
                    - X-authentik-email
                    - X-authentik-name
                    - X-authentik-uid
                    - X-authentik-jwt
                    - X-authentik-meta-jwks
                    - X-authentik-meta-outpost
                    - X-authentik-meta-provider
                    - X-authentik-meta-app
                    - X-authentik-meta-version
    routers:
        default-router:
            rule: "Host(`app.company`)"
            middlewares:
                - name: authentik
            priority: 10
            services: # Unchanged
        default-router-auth:
            match: "Host(`app.company`) && PathPrefix(`/outpost.goauthentik.io/`)"
            priority: 15
            services: http://outpost.company:9000/outpost.goauthentik.io
version: "3.7"
services:
    traefik:
        image: traefik:v2.2
        container_name: traefik
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
        ports:
            - 80:80
        command:
            - "--api"
            - "--providers.docker=true"
            - "--providers.docker.exposedByDefault=false"
            - "--entrypoints.web.address=:80"
    authentik-proxy:
        image: ghcr.io/goauthentik/proxy
        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(`app.company`) && PathPrefix(`/outpost.goauthentik.io/`)
            # `authentik-proxy` refers to the service name in the compose file.
            traefik.http.middlewares.authentik.forwardauth.address: http://authentik-proxy: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,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version
        restart: unless-stopped
    whoami:
        image: containous/whoami
        labels:
            traefik.enable: true
            traefik.http.routers.whoami.rule: Host(`app.company`)
            traefik.http.routers.whoami.middlewares: authentik@docker
        restart: unless-stopped
Create a middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
    name: authentik
spec:
    forwardAuth:
        address: http://outpost.company:9000/outpost.goauthentik.io/auth/traefik
        trustForwardHeader: true
        authResponseHeaders:
            - X-authentik-username
            - X-authentik-groups
            - X-authentik-email
            - X-authentik-name
            - X-authentik-uid
            - X-authentik-jwt
            - X-authentik-meta-jwks
            - X-authentik-meta-outpost
            - X-authentik-meta-provider
            - X-authentik-meta-app
            - X-authentik-meta-version
Add the following settings to your IngressRoute
By default traefik does not allow cross-namespace references for middlewares:
See here to enable it.
spec:
    routes:
        - kind: Rule
          match: "Host(`app.company`)"
          middlewares:
              - name: authentik
                namespace: authentik
          priority: 10
          services: # Unchanged
        # This part is only required for single-app setups
        - kind: Rule
          match: "Host(`app.company`) && PathPrefix(`/outpost.goauthentik.io/`)"
          priority: 15
          services:
              - kind: Service
                # Or, to use an external Outpost, create an ExternalName service and reference that here.
                # See https://kubernetes.io/docs/concepts/services-networking/service/#externalname
                name: ak-outpost-example-outpost
                port: 9000
Enovy (Istio)
info
Requires authentik 2022.6
info
Support for this is still in preview, please report bugs on GitHub.
- Envoy (Istio)
Set the following settings on the IstioOperator resource:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
    name: istio
    namespace: istio-system
spec:
    meshConfig:
        extensionProviders:
            - name: "authentik"
              envoyExtAuthzHttp:
                  # Replace with <service-name>.<namespace>.svc.cluster.local
                  service: "ak-outpost-authentik-embedded-outpost.authentik.svc.cluster.local"
                  port: "9000"
                  pathPrefix: "/outpost.goauthentik.io/auth/envoy"
                  headersToDownstreamOnAllow:
                      - cookie
                  headersToUpstreamOnAllow:
                      - set-cookie
                      - x-authentik-*
                  includeRequestHeadersInCheck:
                      - cookie
Afterwards, you can create AuthorizationPolicy resources to protect your applications like this:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
    name: authentik-policy
    namespace: istio-system
spec:
    selector:
        matchLabels:
            istio: ingressgateway
    action: CUSTOM
    provider:
        name: "authentik"
    rules:
        - to:
              - operation:
                    hosts:
                        # You can create a single resource and list all Domain names here, or create multiple resources
                        - "app.company"