Gateway flow policies (YAML)¶
Flow policies are optional YAML documents that the gateway evaluates on edge routes before a workflow run is started. They complement route auth (EdgeRoute.auth) and route constraints—for example extra headers, external OAuth introspection, product quotas, or declarative transform specifications.
Where they apply¶
- Yes: HTTP requests that hit an EdgeRoute:
POST /v1/api/...(kind: api) andPOST /v1/webhooks/...(kind: webhook). See also Gateway API. - Binding filter: the
policy_binding_filtermechanism only applies when you set it on the workflow invocation; without bindings, behaviour is unchanged (all matching policies).
Direct calls such as POST /v1/run/{workflow} do not run the flow policy engine in the default gateway build—use a path under /v1/api/... instead (static file, discovery, or trigger-derived route).
Location and loading¶
| Environment variable | Default | Meaning |
|---|---|---|
POLICY_DIR |
/app/flows/policies |
Directory containing policy YAML files |
POLICY_CACHE_TTL_SECONDS |
30 |
Refreshes the in-memory policy cache periodically |
- Only
*.yamlfiles directly underPOLICY_DIRare read (no subdirectories). - Each file must be a YAML mapping with at least a
typefield; files withouttypeare skipped. - Policies are loaded in filename sort order; every matching policy is evaluated in that order.
Common fields (all types)¶
| Field | Required | Description |
|---|---|---|
type |
yes | One of: required_headers, oauth_inbound, rate_limit, rate_limit_product, transform |
name |
strongly recommended | Logical name; must be unique and stable if you use policy bindings |
before_auth |
no | When true, the policy runs before route authentication. Type rate_limit defaults to true; other types default to false |
apply_to |
no (default ["*"]) |
Target workflows: exact name or fnmatch patterns (e.g. order-*) |
apply_to_triggers |
no (default ["*"]) |
Trigger context; at the gateway edge this is almost always http. Use * for all triggers |
description |
no | Free text for operators |
Optional limit to named policies¶
If the workflow invocation lists gateway_policy_bindings (array of strings), only policies whose YAML name appears in that list are evaluated—and they must still match apply_to / apply_to_triggers.
Omit gateway_policy_bindings or leave it unset to apply all matching policies (legacy behaviour).
Evaluation order¶
Gateway edge pipeline (per request on /v1/api/* and /v1/webhooks/*):
- Route constraints and payload checks
- Route
rate_limit(edge-route YAML only) - Pre-auth flow policies —
before_auth: trueor typerate_limit - Route auth —
gateway_auth_mode/EdgeRoute.auth - Post-auth flow policies — everything else (default)
Within each policy phase, files are evaluated in filename sort order. Overlapping policies all run; avoid conflicts unless you scope with apply_to.
Supported policy types¶
required_headers¶
Ensures all listed HTTP headers are present (header names matched case-insensitively).
| Field | Type | Description |
|---|---|---|
headers |
list of strings | Header names that must be present |
on_violation |
reject | log |
reject → HTTP 400 with message; log → warning only, request continues |
Example: flows/policies/example-require-headers.yaml
oauth_inbound¶
Validates a Bearer token using OAuth 2.0 token introspection (RFC 7662–style: POST body token=..., JSON response with at least active).
| Field | Type | Description |
|---|---|---|
introspection_url |
string | IdP endpoint; without URL the policy is skipped (warning logged) |
client_id |
string | Optional HTTP Basic auth for the introspection request |
client_secret |
string | Companion to client_id |
required_scopes |
list of strings | After successful introspection: scopes from response scope (space-separated) must include these |
on_violation |
reject | log |
With reject: missing/inactive token → 401, missing scopes → 403; introspection errors may yield 502 |
Note: fields such as cache_ttl_seconds in sample YAML are not implemented in the gateway policy engine; introspection runs per request.
Example: flows/policies/example-oauth-inbound.yaml
rate_limit¶
Fixed-window throttle that can run before authentication (default). Does not call the identity service.
| Field | Type | Description |
|---|---|---|
max_requests |
integer | Maximum requests per window |
window_seconds |
integer | Window length in seconds |
key_from |
ip | authorization | sub |
Bucket key; sub falls back to IP in the pre-auth phase |
before_auth |
boolean | Default true for this type |
on_violation |
reject | log |
Quota exceeded → 429 when reject |
Example: flows/policies/example-rate-limit-ip.yaml
rate_limit_product¶
Applies a quota based on a product from the identity service (IDENTITY_SERVICE_URL, default http://identity:8080). The subject comes from request.state.identity (JWT/API key after gateway auth).
| Field | Type | Description |
|---|---|---|
fallback_product |
string | Product name for callers without an assigned product; quota from fields such as rate_limit_max_requests / rate_limit_window_seconds on the product object or internal defaults |
before_auth |
boolean | When true, runs before route auth using fallback_product and client IP as the bucket (no identity lookup) |
on_violation |
reject | log |
No product and no fallback: with reject → 403; quota exceeded → 429 |
The gateway loads product data via internal HTTP calls; the exact JSON shape depends on the identity API.
Example: flows/policies/example-rate-limit-product.yaml
transform¶
Reads declarative inbound, outbound, and on_error blocks (objects) and collects them in an internal PolicyResult. Intended for pipelines that transform requests/responses (Liquid/XSLT paths, etc.).
| Field | Type | Description |
|---|---|---|
inbound |
object | e.g. template_file pointing at artifacts under flows/ |
outbound |
object | Same for responses |
on_error |
object | Same for error envelopes |
Important: the gateway accumulates these specs during evaluation; whether and how they are applied to request/response in your deployment depends on orchestrator/transform integration. If transforms do not take effect, check your release—the policy file still records the intent.
Example: flows/policies/example-transform-policy.yaml
Operations: shipping policies¶
- Repository / images: place YAML under
flows/policiesand pointPOLICY_DIRat that path in the gateway container. - Dashboard / runtime storage: policies may be managed as runtime assets (Policies in the dashboard); after changes, wait for the gateway cache TTL or restart the gateway for immediate effect.