Traefik Proxy Integration

This guide explains how to integrate heimdall with Traefik Proxy.

Traefik Proxy is a modern HTTP proxy and load balancer for microservices, heimdall can be integrated with via the ForwardAuth Middleware. If heimdall answers with a 2XX code, traefik grants access and forwards the original request to the upstream service. Otherwise, the response from heimdall is returned to the client.

Prerequisites

Traefik makes use of X-Forwarded-* HTTP headers to forward the HTTP method, protocol, host, etc. to the ForwardAuth middleware. By default, heimdall does not trust those. To allow heimdall making use of such headers, you must configure trusted proxies in heimdall’s decision service configuration to contain the IPs or networks of your traefik instances. For test purposes, you can set it to "0.0.0.0/0", which would basically disable the check and let heimdall trust requests from any source.

Traefik can be configured statically, but also load dynamic configuration from many sources managed by so-called providers. The following sections describe how to integrate with heimdall using some of them.

Global Configuration

To let Traefik forward all incoming requests to heimdall, there is a need

  • to configure the ForwardAuth middleware, and

  • to add it to the list of middlewares that are prepended by default to the list of middlewares of each router associated to a named entry point.

Regular Deployment

If you are using Traefik outside of kubernetes, the above can be achieved by the following static configuration

entryPoints:
  web:
    address: ":8080"
    middlewares: (1)
    - heimdall

http:
  middlewares:
    heimdall: (2)
      forwardAuth: (3)
        address: "https://heimdall:4456" (4)
        authResponseHeaders:
        - Authorization (5)
1The list of default middlewares. Here only the middleware named "heimdall" is included. That way, traefik will use this middleware for each and every request.
2The definition of the middleware named "heimdall"
3which is of type forwardAuth
4Configures this middleware to forward requests to a service available under "heimdall" DNS name
5Configures this middleware to forward the Authorization header from heimdall’s response to the upstream service

Kubernetes Deployment

If you are using Traefik as Ingress Controller or as Gateway API implementation in your kubernetes cluster, the required configuration is slightly different. The configuration of the entry point(s) stays the same, but the middleware needs to be deployed as a custom resource.

Here an example for a Middleware custom resource:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: (1)
  name: heimdall
  namespace: heimdall
spec:
  forwardAuth: (2)
    address: "http://heimdall.heimdall.svc.cluster.local:4456" (3)
    authResponseHeaders: (4)
      - Authorization
1The name and the namespace of the middleware. Both are set to heimdall here
2The type of the middleware, which is of type forwardAuth
3Configures this middleware to forward requests to the heimdall service. Here, the corresponding Service is named heimdall and is also located in the namespace named heimdall.
4Configures this middleware to forward the Authorization header from heimdall’s response to the upstream service

How to add this middleware to the default middleware list of a particular endpoint depends on the method used to install Traefik. If helm is used, you can configure that list by making use of the following values.yaml file:

providers:
  kubernetesCRD:
    enabled: true (1)

ports:
  web: (2)
    middlewares:
      - heimdall-heimdall@kubernetescrd (3)
  websecure: (4)
    middlewares:
      - heimdall-heimdall@kubernetescrd
1To let traefik load Middleware resources, like defined above, traefik’s kubernetesCRD provider must be enabled. Typically, it is enabled by default.
2Traefik’s helm chart defines two entry points web for HTTP traffic and websecure for HTTPS traffic. Here we configure the web endpoint to use our middleware
3Reference to the Middleware resource, defined above. The general structure is <middleware name>-<middleware namespace>@<provider>. Since our middleware resource is loaded by the kubernetescrd provider, resides in the heimdall namespace, and is named heimdall, the reference heimdall-heimdall@kubernetescrd is used.
4Here we configure the websecure endpoint, which, as written above, is configured via helm chart for HTTPS traffic. The actual configuration is identical to the configuration for the web endpoint.

Route-based Configuration with Docker

The integration option, described here makes use of the Docker Provider for configuration discovery.

The following docker-compose.yaml file shows a minimal required configuration.

version: '3.7'

services:
  proxy:
    image: traefik:2.11.0
    ports:
    - "9090:9090"
    command: >
      --providers.docker=true (1)
      --providers.docker.exposedbydefault=false
      --entryPoints.http.address=":9090"
    volumes:
    - "/var/run/docker.sock:/var/run/docker.sock:ro" (2)
    # other config options
    labels:
    # other labels
    - traefik.http.middlewares.heimdall.forwardauth.address=http://heimdall:4456 (3)
    - traefik.http.middlewares.heimdall.forwardauth.authResponseHeaders=Authorization (4)

  heimdall:
    image: dadrus/heimdall:dev
    # further config

  upstream:
    # image and config of your upstream service
    labels:
    # other labels
    - traefik.http.routers.upstream.middlewares=heimdall (5)
1This and the next line configures the docker provider
2The docker provider reads the configuration from labels of the services and requires access to the docker socket for this purpose
3Configuration of the ForwardAuth middleware to forward incoming requests to heimdall. The name of middleware is set to "heimdall" here.
4Configuration of the ForwardAuth middleware to forward the Authorization header from heimdall’s response to the upstream service
5Configuration of the required middlewares on the route level of a particular service. Here only the middleware named "heimdall" is referenced. Without that label, traefik will not forward requests to heimdall before routing them to that upstream service.

Traefik as Ingress Controller

If you have Traefik as Ingress Controller in your Kubernetes cluster, you can simply integrate heimdall globally as descibed in Global Configuration chapter above and make use of the standard Ingress resource.

If you are using traefik’s proprietary IngressRoute custom resource instead of kubernetes standard Ingress one, you can also reference the Middleware resource locally. This option is shown in the snippet below.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata: (1)
  name: demo-app
  namespace: demo
spec:
  entryPoints:
    - web (2)
  routes:
    - kind: Rule
      match: Host(`demo-app.local`) && PathPrefix(`/`)
      middlewares: (3)
        - name: heimdall
          namespace: heimdall
      services: (4)
        - kind: Service
          name: demo-app
          namespace: demo
          port: app-port
1metadata, like name and the namespace of the IngressRoute resource
2The traefik entry points to attach this resource to. Here only web entry point is referenced
3List of the middlewares to be applied. Here the Middleware named heimdall in the namespace heimdall is referenced.
By default, IngressRoute resources are not allowed to reference resources in namespaces different from the own namespace. If your Middleware resource, like also shown here, is deployed in another namespace, you have to allow that. If traefik is installed via helm, it can be achieved by setting providers.kubernetesCRD.allowCrossNamespace to true (See also here).
4The reference to the Service, the requests should be forwarded to.

Traefik as Gateway API implementation

If you have Traefik as Gateway API implementation in your Kubernetes cluster, you can simply integrate heimdall globally as descibed in Global Configuration chapter above and make use of the standard HTTPRoute resource.

Additional Resources

A fully working example with Traefik is shown in the Protect an Application quickstart and is also available on GitHub.

Last updated on Sep 16, 2024