Skip to content

Traefik Authorization Proxy

Overview

Customer-Managed Prefect supports three authorization modes for its service mesh:

Mode Value Istio required? Description
Istio Policy (default) policy Yes Uses Istio AuthorizationPolicy CRDs with an external auth provider
Traefik Proxy proxy Yes Deploys a Traefik instance that enforces auth via forwardAuth middleware
Traefik Only traefik No Traefik handles all routing and auth directly; no Istio at all

For the traefik (no-Istio) mode, see Traefik-Only Mode.

The proxy mode documented on this page is useful when your environment cannot use Istio AuthorizationPolicy custom resources. For example, when the Istio control plane does not have an extensionProvider configured, or when you prefer to centralize auth enforcement in a single proxy rather than distributing it across sidecar policies.

Traefik version

The chart defaults to Traefik v3 (3.6.13) as of chart 1.3.2 (April 17, 2026). Traefik v2 remains supported for existing deployments.

The image tag you set under serviceMesh.routing.authProxy.image.tag selects which configmap template the chart renders:

  • Tags starting with 3 or the string latest render the v3 configmap.
  • All other tags render the v2 configmap.

To pin to Traefik v2, override the tag in your values-override.yaml:

serviceMesh:
  routing:
    authProxy:
      image:
        tag: 2.11.42

New deployments should use the v3 default. Existing v2 deployments can upgrade by accepting the new chart default on their next chart upgrade. No configuration changes are required. The rendered v3 configmap is functionally equivalent to the v2 configmap for the routing, forwardAuth, and CORS behavior documented on this page.

How it works

When serviceMesh.authorizationMode: proxy is set, the chart deploys a Traefik instance (prefect-auth-proxy) that sits in front of the Istio ingress gateway. All inbound traffic is routed through Traefik first:

External request
      │
      ▼
prefect-auth-proxy (Traefik, port 8080)   ◄── your ingress / LB points here
      │
      ├─ public paths ──────────────────────────► prefect-istio-gateway
      │  (no auth check)
      │
      └─ all other paths ──► forwardAuth (auth:4300) ──► prefect-istio-gateway
                                   │
                            200 OK: allow
                            4xx:    deny

Traffic reaches the proxy however your platform delivers it — a cloud load balancer, an Nginx ingress, a NodePort, or an Istio edge VirtualService (see serviceMesh.routing.edgeVirtualService). The proxy itself has no dependency on any particular ingress mechanism.

Traefik defines two routers:

  • public (priority 2): Forwards the following paths without authentication:

    • /auth
    • /api/docs, /api/openapi.json, /api/health, /api/version
    • /hooks
    • /{prefix}/task_runs/subscriptions/scheduled
    • /{prefix}/events/out
    • The configured frontend path prefix (if edgeVirtualService.pathPrefix.frontend is set)
  • authenticated (priority 1): All other paths go through the forwardAuth middleware, which delegates the auth decision to http://auth:4300/. If the auth service returns HTTP 200 the request is allowed; any other response denies it.

The auth service receives the following headers from the original request, and may return the following headers that are forwarded upstream:

Direction Headers
To auth service authorization, Origin, Access-Control-Request-Method
From auth service x-nebula-actor-id, x-nebula-actor-permissions, x-nebula-ratelimit-config, x-nebula-log-limit-config

Enabling proxy mode

Set serviceMesh.authorizationMode to proxy in your values-override.yaml:

serviceMesh:
  authorizationMode: proxy

When this is set the chart will:

  • Create: a ServiceAccount, Service, Deployment, ConfigMap, and HorizontalPodAutoscaler for the Traefik proxy
  • Skip: all Istio AuthorizationPolicy CRDs (the auth-policy.yaml template is gated on authorizationMode: policy)
  • Route: the edge VirtualService to prefect-auth-proxy:8080 instead of directly to prefect-istio-gateway:80

Pointing your ingress at the proxy

When authorizationMode: proxy is enabled, all API traffic must be routed to the prefect-auth-proxy service on port 8080 rather than directly to prefect-istio-gateway. If traffic bypasses the proxy, requests will reach the backend without any auth enforcement.

Chart-managed ingress (automatic)

If you use the chart's built-in ingress.enabled: true, the backend is switched automatically — no further action is required.

Bring-your-own ingress

If you manage your own ingress resource outside the chart, update its API backend to target prefect-auth-proxy:8080. The UI ingress is not affected — it continues to point directly at prefect-istio-gateway:80.

Nginx ingress (networking.k8s.io/v1)

# API ingress — route through the auth proxy
spec:
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: prefect-auth-proxy   # was: prefect-istio-gateway
                port:
                  number: 8080             # was: 80
---
# UI ingress — still points directly at the Istio gateway (unchanged)
spec:
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: prefect-istio-gateway
                port:
                  number: 80

Nginx ingress with nginx.ingress.kubernetes.io/upstream-vhost

Traefik uses the Host header for routing decisions. If your ingress rewrites the host, add the annotation so the original host is preserved:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/upstream-vhost: api.example.com

Istio edge VirtualService

If you use an Istio VirtualService as your edge routing layer, update the API destination. The UI VirtualService continues to route directly to prefect-istio-gateway:

# API VirtualService — route through the auth proxy
spec:
  hosts:
    - api.example.com
  http:
    - route:
        - destination:
            host: prefect-auth-proxy   # was: prefect-istio-gateway
            port:
              number: 8080             # was: 80
---
# UI VirtualService — still points directly at the Istio gateway (unchanged)
spec:
  hosts:
    - app.example.com
  http:
    - route:
        - destination:
            host: prefect-istio-gateway
            port:
              number: 80

Forwarded headers

If your ingress or LB adds X-Forwarded-For / X-Forwarded-Proto headers, make sure Traefik is configured to trust them. For example, to trust all forwarded headers (appropriate when Traefik is behind a trusted internal proxy):

serviceMesh:
  routing:
    authProxy:
      extraArgs:
        - --entrypoints.api.forwardedHeaders.insecure

For more advanced configurations such as restricting trust to specific IP ranges, consult the Traefik forwarded headers documentation.

Configuration reference

All proxy configuration lives under serviceMesh.routing.authProxy:

serviceMesh:
  authorizationMode: proxy
  routing:
    authProxy:
      # Traefik image. Defaults to v3; tags starting with `2` render the v2
      # configmap, while tags starting with `3` or `latest` render the v3
      # configmap.
      image:
        repository: traefik # override to pull from your internal registry
        tag: 3.6.13

      # Resource limits for the Traefik container
      resources:
        requests:
          cpu: 100m
          memory: 100Mi
        limits:
          cpu: 200m
          memory: 200Mi

      # Static replica count (ignored when autoscaling.enabled=true)
      replicas: 2

      # Horizontal Pod Autoscaler
      autoscaling:
        enabled: true
        minReplicas: 2
        maxReplicas: 5

      # Log level for the Traefik container (debug | info | warn | error)
      logLevel: info

      # Name used for all proxy Kubernetes resources
      name: prefect-auth-proxy

      # Pass-through labels and annotations applied to all proxy resources
      labels: {}
      annotations: {}

      # Extra CLI args appended to the Traefik container command
      extraArgs: []

      # Node scheduling
      nodeSelector: {}
      tolerations: []

Choosing between modes

Consideration policy (Istio) proxy (Traefik)
Requires Istio extensionProvider in MeshConfig Yes No
Auth enforcement Distributed (per-service sidecar) Centralized (single proxy)
Extra deployment No Yes (prefect-auth-proxy)
CORS handling Application/sidecar Traefik middleware
Suitable for strict Istio-only environments Yes Not required

If your Istio control plane already has authz-http-redirect configured as an extension provider, prefer the default policy mode — it enforces auth closer to each service and does not introduce an additional hop. Use proxy mode when the Istio extension provider cannot be configured or when your platform team prefers an explicit proxy in the traffic path.