Head Classifier
Classifies each request from its head (path) and promotes the class as a reserved x-praxis-head-class header that the router matches to pick an upstream
Versions marked “overview” do not contain this page. Selecting one opens that version’s documentation overview.
Category: Setup-dependent integration
Task: Classifies each request from its head (path) and promotes the class as a reserved x-praxis-head-class header that the router matches to pick an upstream
Prerequisites: The external service, credentials, or certificates referenced by this configuration.
This configuration comes from the selected release. The example has not been run here; external services are not bundled.
Download the source file.
# Head Classifier Routing
#
# Classifies each request from its head (path) and promotes the class as a
# reserved x-praxis-head-class header that the router matches to pick an upstream.
# Classification runs in the request-head phase, before any request body is read.
#
# ┌────────┐
# │ client │
# └───┬────┘
# │
# ┌───▼─────────────────┐
# │ proxy :8080 │
# │ head_classifier ─┐ │ /api/* -> class api
# │ │ │ /assets/* -> class assets
# │ guardrails <───┤ │ (class api) inspect body
# │ router <───┘ │ (default) -> class other
# └───┬────────┬────────┘
# │ │ │
# ┌───▼──┐ ┌───▼───┐ ┌──▼────┐
# │ api │ │assets │ │ other │
# │ 3001 │ │ 3002 │ │ 3003 │
# └──────┘ └───────┘ └───────┘
#
# Because head_classifier runs in the request-head phase (before any body is
# read), the promoted x-praxis-head-class header is already set when a later
# body-inspecting filter runs during the StreamBuffer pre-read. The guardrails
# filter below is gated on that header, so it inspects bodies only for class
# `api`: this demonstrates — and guards against regressing — the head phase
# running before the body pre-read.
#
# Usage:
# cargo run -p praxis-proxy -- -c examples/configs/traffic-management/head-classifier.yaml
# curl http://localhost:8080/api/users # -> api backend
# curl http://localhost:8080/assets/app.js # -> assets backend
# curl http://localhost:8080/home # -> other backend
# # 403: class api body guardrails block a forbidden body
# curl -d 'forbidden' http://localhost:8080/api/users
# # 200: class other skips guardrails, forbidden body reaches the backend
# curl -d 'forbidden' http://localhost:8080/home
listeners:
- name: default
address: "127.0.0.1:8080"
protocol: http
filter_chains: [main]
filter_chains:
- name: main
filters:
- filter: head_classifier
rules:
- path_prefix: "/api/"
class: api
- path_prefix: "/assets/"
class: assets
default_class: other
# Inspect bodies only for the head-promoted `api` class. The gate header
# is set in the request-head phase, before this body filter reads the
# body during pre-read, so class `api` requests are inspected while other
# classes skip guardrails entirely.
- filter: guardrails
conditions:
- when:
headers:
x-praxis-head-class: api
rules:
- target: body
contains: "forbidden"
- filter: router
routes:
- path_prefix: "/"
headers:
x-praxis-head-class: api
cluster: api-backend
- path_prefix: "/"
headers:
x-praxis-head-class: assets
cluster: assets-backend
- path_prefix: "/"
headers:
x-praxis-head-class: other
cluster: other-backend
- filter: load_balancer
clusters:
- name: api-backend
endpoints:
- "127.0.0.1:3001"
- name: assets-backend
endpoints:
- "127.0.0.1:3002"
- name: other-backend
endpoints:
- "127.0.0.1:3003"
insecure_options:
allow_private_endpoints: true # example proxies to local backends
skip_pipeline_checks:
# Guardrails runs only for the head-promoted `api` class; acknowledge the
# conditional-security bypass for other classes explicitly.
conditional_security: true