Multi-Layer Routing
Overview
Multi-layer routing enables you to create hierarchical relationships between routers, where parent routers can process requests through middleware before child routers make final routing decisions.
This feature allows middleware at the parent level to modify requests (adding headers, performing authentication, etc.) that influence how child routers evaluate their rules and route traffic to services.
Multi-layer routing is particularly useful for progressive request enrichment, where each layer adds context to the request, enabling increasingly specific routing decisions:
- Authentication-Based Routing: Parent router authenticates requests and adds user context (roles, permissions) as headers, child routers route based on these headers
- Staged Middleware Application: Apply common middleware (rate limiting, CORS) at parent level (for a given domain/path), but specific middleware at child level
Multi-layer routing is supported by the following providers:
- File provider (YAML, TOML, JSON)
- KV stores (Consul, etcd, Redis, ZooKeeper)
- Kubernetes CRD (IngressRoute)
Multi-layer routing is not yet available for other providers (Docker, Kubernetes Ingress, Gateway API, etc.).
How It Works
- Request arrives at an entrypoint
- Parent router matches based on its rule (e.g.,
Host(`example.com`)) - Parent middleware runs, potentially modifying the request
- One child router matches based on its rule (which may use modified request attributes)
- Request is forwarded to the matching child router's service
Building a Router Hierarchy
Root Routers
- Have no
parentRefs(top of the hierarchy) - Can have tls,
observability, andentryPointsconfiguration - Can be either parent routers (with children) or standalone routers (with service)
- Can have models applied (non-root routers cannot have models)
Intermediate Routers
- Reference their parent router(s) via
parentRefs - Have one or more child routers
- Must not have a service defined
- Must not have
entryPoints, tls, orobservabilityconfiguration
Leaf Routers
- Reference their parent router(s) via
parentRefs - Must have a service defined
- Must not have
entryPoints, tls, orobservabilityconfiguration
Configuration Example
This example demonstrates a authentication based multi-layer routing configuration where a parent router authenticates requests and adds user context as headers, and child routers route based on these headers.
- Parent Router
- Child Router
- Middleware
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-parent
namespace: apps
spec:
entryPoints:
- websecure
routes:
- match: PathPrefix(`/api`)
kind: Rule
middlewares:
- name: auth-middleware
# Note: No services defined - this is a parent router
tls: {}
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: api-routing-logic
namespace: apps
spec:
parentRefs:
- name: api-parent
namespace: apps
routes:
- match: HeadersRegexp(`X-User-Role`, `admin`)
kind: Rule
services:
- name: admin-service
port: 8080
- match: HeadersRegexp(`X-User-Role`, `user`)
kind: Rule
services:
- name: user-service
port: 8080
- match: PathPrefix(`/`)
kind: Rule
priority: 0 # Explicit catch-all with lowest priority
services:
- name: default-service
port: 8080
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: auth-middleware
namespace: apps
spec:
forwardAuth:
address: "http://auth-service.apps.svc.cluster.local:8080/auth"
authResponseHeaders:
- X-User-Role
- X-User-Name
How it works
- Request to
/api/endpointmatchesapi-parentrouter auth-middleware(ForwardAuth) validates the request and addsX-User-Roleheader- Modified request is evaluated by child routes in
api-routing-logic:- If
X-User-Role: admin→ routes toadmin-service - If
X-User-Role: user→ routes touser-service - Otherwise → catch-all route (priority 0) forwards to
default-service
- If
The catch-all route uses priority: 0 (lowest priority) to ensure it only matches when more specific routes don't match. Priorities matter in multi-layer routing - shorter matchers or explicit priority 0 should be used for
catch-all routes.