Enriching a flow
GuideOperationsSince version 0.1.0
Operations guide: configure, deploy and observe the gateway. What the capability does, product side: product guide; calling it: developer guide.
Goal: set a header, rewrite a path, add a parameter - without touching the upstream or the gateway's code.
Command - a named policy in flexway.yaml, attached in the contract to one operation:
policies:
definitions:
enrich:
type: header-inject
when: "has(auth.subject)" # CEL: authenticated callers only
config:
set:
x-plan: "{{ auth.claims.plan }}" # a CEL expression between braces
on_missing: skip # skip | empty | fail - required as soon as a value is an expressionpaths:
/orders/{id}:
get:
x-flexway-policies: [enrich] # this operation, and this one onlyLevels add up - policies.chains.global, .hosts.<host>, .routes."/orders/**", then the
operation - and the most precise wins. !name removes an inherited policy:
x-flexway-policies: ["!enrich"].
Check: the upstream receives x-plan on GET /orders/{id} and on no other operation; /config
(admin port) shows each operation's chain under effective_chains. A policy writing a protected
header - Authorization, X-Forwarded-*, tracing, the tenant header - prevents the start.
The types of
0.1.0:header-inject,header-remove(request, response, refusal),rewrite-path,query-inject,query-remove. None reads the body: a stream stays unbuffered.
A value that is not text in a {{ … }} template (header-inject, query-inject) always
renders the same way:
| Value | Rendering |
|---|---|
| Text | As is; null or absent: nothing (then on_missing if the expression fails) |
| Number, boolean | Decimal, never in exponent form (1700000000, not 1.7e+09); true, false |
| List | Elements separated by a comma, the list syntax of HTTP fields (RFC 9110 §5.6.1): ["seller","admin"] -> seller,admin; an empty or null element left out; a list or object element as JSON |
| Object | Compact JSON, keys sorted |
For another delimiter, join - the function of CEL's strings extension, the one Kubernetes enables:
"{{ auth.claims.roles.join(' ') }}" -> seller admin, join() with no delimiter. A list holding
anything but text makes join fail: the value is missing, on_missing decides. An unknown function
refuses the load. An element holding a comma is not quoted: pick another delimiter with join.