Skip to content

Traefik-Only Mode

Experimental

authorizationMode: traefik is experimental. The configuration surface and behavior may change in future chart releases as the feature stabilizes. Do not use in production without coordinating with your Prefect contact first.

Available from chart version 1.2.6 (January 2026 release) and 1.3.4 (April 2026 release).

Overview

Traefik-only mode deploys Customer-Managed Prefect without any Istio dependency. Traefik replaces the Istio ingress gateway and handles all inbound routing and auth enforcement directly.

The traefik authorization mode is the third option in the service mesh configuration:

Mode Value Istio required? Description
Istio Policy (default) policy Yes Istio AuthorizationPolicy CRDs with an external auth provider
Traefik Proxy proxy Yes Traefik fronting the Istio gateway; auth enforced at the proxy
Traefik Only traefik No Traefik handles all routing and auth directly; no Istio at all

Why choose Traefik-only mode

Traefik mode is suited for customers who cannot install Istio — for example, when cluster security policy or governance rules prohibit Istio CRDs or sidecar injection. It removes the istiod, sidecar, and Istio CRD dependency entirely, which can simplify the initial deployment and ongoing upgrades.

If your cluster already runs Istio, or if an Istio installation is feasible, use policy or proxy mode instead — traefik mode is newer and has seen less production use than the Istio modes.

How it works

External request
      │
      ▼
prefect-auth-proxy (Traefik, port 8080)   ◄── your ingress / LB points here
      │
      ├─ UI domain host (non-/api/ paths) ─────────────────────► ui
      │
      ├─ public API paths (auth, webhooks, events/out, ────────► individual services
      │  task subscriptions, health, docs)                        (no auth check)
      │
      └─ all other API paths ──► forwardAuth (auth:4300) ──────► individual services
                                       │
                                200 OK: allow
                                4xx:    deny

Unlike proxy mode, there is no Istio gateway between Traefik and the backend services. Traefik routes directly to each Prefect service.

Limitations

Traefik mode does not fully replicate all capabilities of the Istio modes:

  • No connection pooling or outlier detection — Istio DestinationRule resources provide these; there is no equivalent in traefik mode.
  • Maintenance mode returns no response body — In Istio modes, maintenance mode returns a structured JSON body. Traefik mode returns a plain 503 with Prefect-Maintenance: true and Retry-After: 1200 headers but no body. Current Prefect clients use the header to detect maintenance; the body is informational only.
  • Per-route timeouts are approximated — Istio VirtualService supports per-route timeouts. Traefik mode groups services into named transport configs with shared timeout values; individual route-level timeout overrides are not supported.
  • Experimental status — The routing configuration is managed entirely within the chart and is not customer-configurable beyond the values documented below. The routing table may change between chart versions.

Enabling Traefik-only mode

Set the following in your values-override.yaml:

serviceMesh:
  authorizationMode: traefik
  routing:
    frontend:
      hosts: ["my-instance-ui.example.com"]
    backend:
      hosts: ["my-instance-api.example.com"]

istio:
  gateway:
    enabled: false

Note

istio.gateway.enabled: false is required. The chart will fail with a validation error if authorizationMode: traefik is combined with istio.gateway.enabled: true.

When this configuration is applied, the chart:

  • Creates a ServiceAccount, Service, Deployment, ConfigMap, and HorizontalPodAutoscaler for the Traefik proxy (prefect-auth-proxy)
  • Skips all Istio resources: VirtualService, DestinationRule, AuthorizationPolicy, EnvoyFilter, and the Istio gateway deployment
  • Routes both frontend and backend ingress to prefect-auth-proxy:8080 by default

Traefik version

Traefik mode requires Traefik v3. The chart defaults to 3.6.13. To override:

serviceMesh:
  routing:
    authProxy:
      image:
        tag: "3.6.14"

Note

maxResponseBodySize on the forwardAuth middleware requires Traefik ≥ 3.6.9. Older v3 tags work but will log a warning about missing maxResponseBodySize.

Ingress setup

In traefik mode, your external ingress (cloud load balancer, Nginx ingress controller, etc.) should point both the frontend and backend at prefect-auth-proxy:8080. Traefik uses the Host header to separate UI traffic from API traffic internally, so both domains share the same backend service.

Chart-managed ingress (automatic)

If you use the chart's built-in ingress.enabled: true, both frontend and backend are pointed at prefect-auth-proxy:8080 automatically — no further configuration is required.

Bring-your-own ingress

If you manage your own ingress resource outside the chart, point both the frontend and backend rules at prefect-auth-proxy:8080:

# UI ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  rules:
    - host: my-instance-ui.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: prefect-auth-proxy
                port:
                  number: 8080
---
# API ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
spec:
  rules:
    - host: my-instance-api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: prefect-auth-proxy
                port:
                  number: 8080

The chart-managed ingress with ingress.class: gce handles this automatically. For a custom GKE ingress:

metadata:
  annotations:
    kubernetes.io/ingress.class: gce
    kubernetes.io/ingress.allow-http: "false"
spec:
  rules:
    - host: my-instance-ui.example.com
      http:
        paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              service:
                name: prefect-auth-proxy
                port:
                  number: 8080
    - host: my-instance-api.example.com
      http:
        paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              service:
                name: prefect-auth-proxy
                port:
                  number: 8080

Forwarded headers

If your ingress or load balancer sets X-Forwarded-For / X-Forwarded-Proto headers, configure Traefik to trust them. To trust all forwarded headers (appropriate when Traefik is behind a trusted internal proxy):

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

For IP-range-restricted trust, see the Traefik forwarded headers documentation.

Migrating from an Istio mode

If you are migrating an existing deployment from policy or proxy mode to traefik mode:

  1. Remove sidecar injection from the namespace:

    kubectl label namespace prefect istio-injection-
    kubectl label namespace prefect istio.io/rev-
    
    Leaving injection enabled will not break routing, but it injects unnecessary Envoy sidecars into every pod.

  2. Restart pods to remove existing sidecar containers:

    kubectl rollout restart deployment -n prefect
    

  3. Verify the ingress points to prefect-auth-proxy:8080 for both frontend and backend. The chart manages this automatically when using ingress.enabled: true.

  4. Remove the prefect-istiod Helm release if it is no longer needed by other workloads in your cluster.

Configuration reference

serviceMesh:
  authorizationMode: traefik   # required

  routing:
    authProxy:
      # Traefik v3 image. Traefik-only mode requires v3.
      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

      # Extra CLI args appended to the Traefik container command
      extraArgs: []
        # Uncomment to trust all X-Forwarded-* headers from upstream ingress:
        # - --entrypoints.api.forwardedHeaders.insecure

      # Node scheduling
      nodeSelector: {}
      tolerations: []

    frontend:
      # Required: Traefik uses this hostname to separate UI traffic from API traffic.
      hosts: ["my-instance-ui.example.com"]

    backend:
      hosts: ["my-instance-api.example.com"]

istio:
  gateway:
    enabled: false   # required when authorizationMode: traefik