Configuring Claim-Based Multi-Layer Routing with Traefik and Entra ID

Configuring Claim-Based Multi-Layer Routing with Traefik and Entra ID

Routing often needs to be more than just simple path matching. You might need to route a specific user to a particular version of a service, or perform identity-based canary releases. This post covers how to use Traefik Hub's Multi-Layer Routing with Entra ID (OIDC) to build a dynamic, claim-based routing system.

The Goal: Context-Aware Routing

The objective is to decouple authentication logic from granular service routing. We want a central point for identity verification, but with the ability to route traffic to different backends based on who is logged in.

Phase 1: Identity Extraction via OIDC

The first step is configuring the OIDC middleware to talk to Microsoft Entra ID. Beyond just securing the endpoint, we need to extract identity metadata (JWT claims) and present them as standard HTTP headers. 

SSO to initiate the OIDC flow

Initial authentication flow via Entra ID.

 Viewing raw JWT claims like "name" on jwt.io.

We use the forwardHeaders configuration to map these claims:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: oidc
spec:
  plugin:
    oidc:
      # ...
      forwardHeaders:
        X-User-name: name   # Maps the 'name' claim to a custom header
        X-User-Id: sub      # Maps 'sub' to a unique ID header

When a user authenticates, Traefik Hub injects these headers into the request before it reaches the routing logic.

Phase 2: Multi-Layer Routing Implementation

Traefik Hub's Multi-Layer Routing allows us to split routing into "Parent" and "Child" resources. This separates global concerns like TLS and Auth from service-specific rules.

The Parent Route: Security and TLS

The Parent route is responsible for host matching and applying the OIDC middleware.

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-lke-route-parent
spec:
  entryPoints: [websecure]
  routes:
    - kind: Rule
      match: Host(`gw.internal.carlos.traefik.ai`)
      middlewares:
        - name: oidc

The Child Route: Identity-Based Logic

The Child route references the Parent and defines rules based on the headers injected by the OIDC middleware.

In this scenario:

  • Amer is routed to the Petstore API.
  • Carlos is routed to the Httpbin API.
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-lke-route-child
spec:
  parentRefs:
    - name: traefik-lke-route-parent
  routes:
    - match: Header(`X-User-name`, `Carlos`)
      kind: Rule
      services:
        - name: httpbin-svc
          port: 443
    - match: Header(`X-User-name`, `Amer`)
      kind: Rule
      services:
        - name: petstore-svc
          port: 443
API routed X-User-Name = Carlos

 

API routed X-User-Name = Amer

Dynamic routing based on user identity.

Key Advantages

  1. Modular Configuration: Parent routes manage infrastructure (TLS, DNS, Auth), while Child routes focus on business logic.
  2. Claim-to-Header Mapping: Turning OIDC claims into headers makes them actionable by standard Traefik routing rules.
  3. Simplified Maintenance: You only define your authentication logic once in the Parent route. Every Child route inherits this security context automatically.

By combining Entra ID claims with Traefik Hub's routing flexibility, you can implement sophisticated traffic management strategies that are both secure and easy to manage.

Read more