Configuration reference
Every key of flexway.yaml, every policy type, every contract extension and the gRPC option of Flexway v1.7.1, read from the JSON Schema the release ships: type, allowed values, default, bounds, version it arrived in, reload.
Validate in the editor
One line at the top of flexway.yaml is all editors that use yaml-language-server need: they complete keys, show their description and flag a mistake as you type - unknown key, value off the list, badly written duration - rather than at startup.
# yaml-language-server: $schema=https://flexway.io/schema/v1/flexway.schema.json
version: 1The schemas of the published release (JSON Schema 2020-12), served at their identifier:
https://flexway.io/schema/v1/architecture.schema.jsonhttps://flexway.io/schema/v1/contract-extensions.schema.jsonhttps://flexway.io/schema/v1/flexway.schema.jsonhttps://flexway.io/schema/v1/policy-fragment.schema.json
The schema describes; flexway validate decides. What spans several files - an upstream for every operation of the contract, a named policy that does not exist - is checked only by flexway validate and at startup: keep it in CI.
390 keys
flexway.yaml
The gateway's configuration file: it says how things are served, never what. It lists no operation - it references the contracts and describes upstreams, hosts, identities and policies. Decoding is strict: an unknown key is refused, and every problem is reported at once.
agents
What agents reach: the MCP surface, the bounds of delegation chains and A2A governance. No tool is listed here: an operation becomes a tool in the contract (x-flexway-tool).
- Type
object- Since
- 0.1.0
- Reload
- hot
agents.a2a
The deployment's side of A2A governance: what the declared agent cards (contracts.a2a) do not say.
- Type
object- Since
- 1.2.0
- Reload
- hot
agents.a2a.push
Guard of the push notification targets a caller hands an upstream agent. Absent or empty: every push notification configuration is refused - closed by default.
- Type
object- Since
- 1.2.0
- Reload
- hot
agents.a2a.push.allowed_hosts
Host names a push notification may target: an exact name, or *.domain for its subdomains, each with an optional :port, in lower case. Never an IP address, a bare * or localhost; a duplicate entry is refused.
- Type
list<string>- Since
- 1.2.0
- Reload
- hot
agents.delegation
Bounds the chains of agents acting for a person (RFC 8693 act claim) and lets a revocation break them. Absent: a delegated token is accepted like any other. When set, every issuer of auth.issuers must declare client, for introspection.
- Type
object- Since
- 0.1.0
- Reload
- hot
agents.delegation.introspection
How a revocation is seen: delegated tokens are introspected at their issuer (RFC 7662).
- Type
object- Since
- 0.1.0
- Reload
- hot
agents.delegation.introspection.cache
How long an introspection answer is reused - the longest a revoked chain keeps working. A duration (10s); default 10s.
- Type
string- Default
10s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
agents.delegation.max_age
Maximum age of a chain, counted from the person's authentication (auth_time, else iat). A duration (15m); default 15m. A contract may tighten it per operation, never widen it.
- Type
string- Default
15m- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
agents.delegation.max_depth
How many agents a chain may hold. A non-negative integer; 0 accepts no delegated token; default 2. A contract may tighten it per operation, never widen it.
- Type
integer- Default
2- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
agents.mcp
The Model Context Protocol surface: where it is served, and as what resource. Operations marked x-flexway-tool are offered there as tools under the same decision as REST; the token received is never relayed upstream.
- Type
object- Since
- 0.1.0
- Reload
- hot
agents.mcp.clients
When set, the only OAuth clients admitted on the surface, named by the URL of their Client ID Metadata Document: an exact https URL, or a prefix ending with /*. Absent: any client.
- Type
list<string>- Since
- 1.0.0
- Reload
- hot
agents.mcp.path
Path the MCP surface answers on, on every host of resources. A literal path starting with /, without {, } or *; default /mcp.
- Type
string- Default
/mcp- Since
- 0.1.0
- Reload
- hot
agents.mcp.resources
Maps each host that serves the surface to its public URL - the audience a token must carry to be accepted there (RFC 8707). An absolute https URL (http for localhost only), without query or fragment, ending in path. Required and non-empty; declared, never derived from the request.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers
Existing MCP servers whose tools the surface serves too (federation), under their original names, with the gateway's authorization, quota and metrics in front. The key names the server.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.discovery
How the server's tools are listed. Discovery runs in the background and never blocks the start.
- Type
object- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.discovery.issuer
Name of an issuer of auth.issuers, with a client, from which the gateway obtains a client_credentials token to list the tools - for a server that requires a token even for that. Absent: listed anonymously.
- Type
string- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.discovery.refresh
How often the tools are listed again. A duration (5m); default 5m.
- Type
string- Default
5m- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.hosts
MCP surfaces (hosts of agents.mcp.resources) that serve this server. Empty: every surface.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.rate_classes
A tool's rate-limit class, by original name (a served tool). Otherwise read when the server announces the tool read-only, write otherwise.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.rename
Gives a tool another name on the surface, by original name - against a collision, for instance. The tool must be in tools.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.scopes
Scopes required for every tool of the server. Empty: an authenticated caller is enough.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.tool_scopes
Replaces scopes for one tool, by original name; the tool must be in tools.
- Type
map<list<string>>- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.toolsrequired
Tools served: a declared list of names - the closed default - or "*" for whatever the server announces, chosen explicitly. Required.
- Type
"*" | list<string>- Allowed values
*- Since
- 0.1.0
- Reload
- hot
agents.mcp.servers.*.upstreamrequired
Name of an upstream of upstreams with protocol: mcp: where the server is, with the pool, budgets, breaker, bulkhead and token exchange that come with it. Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai
The inference surface /v1/* (OpenAI-compatible) served by the data plane, routed by policy to backends, under per-tenant token and euro budgets. Absent: not served. No contract to write: its operations are built in.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.backends
Inference backends, by name. At least one. A backend is declared by kind, capabilities, authentication and metering; no provider is named: a provider is a URL, an authentication and a price.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
ai.backends.*.api_keysecret
The backend's key, sent as a Bearer token - a reference (${VAR} or file:/path), read at each use. Empty for a keyless internal backend. Exclusive with auth (equivalent to auth: { scheme: bearer, key: ... }).
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 0.1.0
- Reload
- hot
ai.backends.*.auth
How the gateway authenticates to the backend, exactly one scheme. Absent: api_key as a Bearer token, else none.
- Type
object- Since
- 1.5.0
- Reload
- hot
ai.backends.*.auth.header
Name of the header the key is sent in: the header scheme only, and required there.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.auth.keysecret
The key sent, by reference (${VAR} or file:/path), read again at each call: the bearer and header schemes. Never a key in clear.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.5.0
- Reload
- hot
ai.backends.*.auth.path
File a short-lived token is read from at each call, as a workload identity projects it; sent as a Bearer token. The token_file scheme only, and required there.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.auth.schemerequired
Authentication scheme: none (nothing), bearer (Authorization: Bearer <key>), header (the key in the header header), token_file (a token read from path). Required in auth.
- Type
string- Allowed values
nonebearerheadertoken_file- Since
- 1.5.0
- Reload
- hot
ai.backends.*.capabilities
What the backend serves: chat, vision (serves text too), embeddings, model (a specialised model, grpc backends only). No duplicate. Empty: chat, or model for a grpc backend.
- Type
list<string>- Allowed values
chatvisionembeddingsmodel- Since
- 1.5.0
- Reload
- hot
ai.backends.*.default_model
Model served when the caller asks for none of models. Required, except for a relay (the gateway it relays to chooses) and a grpc backend.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.backends.*.external
Marks a third party: a sensitive request never goes there. A boolean; unset: false, except for a relay, external unless the operator declares external: false.
- Type
boolean- Since
- 0.1.0
- Reload
- hot
ai.backends.*.fallback
Backends tried in turn when this one fails before answering (connection, 5xx, timeout, open breaker), each once; never on a 4xx, nor after a stream's first byte, nor to an external backend for a sensitive request. Names of ai.backends, not itself, no duplicate, never a grpc backend.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
ai.backends.*.identity_headers
Header names a relay backend receives the call's tenant, agent and sensitivity under - those the other gateway declares in auth.trusted_headers and ai.sensitive_header. For the relay kind only, where tenant is required.
- Type
object- Since
- 1.5.0
- Reload
- hot
ai.backends.*.identity_headers.agent
Name of the header carrying the calling agent toward the relay. Optional.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.identity_headers.sensitive
Name of the header carrying the call's sensitivity toward the relay. Optional.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.identity_headers.tenant
Name of the header carrying the call's real tenant toward the relay. Required for a relay: the gateway it reaches must see the real tenant, not a single caller.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.kind
Backend kind: openai (any OpenAI-compatible API, the default), relay (another Flexway, spoken to as OpenAI with the call's identity under declared headers), grpc (a specialised model served by a method of a gRPC contract, never a target of /v1/*).
- Type
string- Allowed values
openairelaygrpc- Default
openai- Since
- 1.5.0
- Reload
- hot
ai.backends.*.metering
Who counts the cost: local (the default, this gateway counts and caps) or upstream (the gateway it relays to counts; this one still applies its own local cap). upstream is refused on an openai backend.
- Type
string- Allowed values
localupstream- Default
local- Since
- 1.5.0
- Reload
- hot
ai.backends.*.models
Models a caller may ask for by name; any other is served default_model. No empty entry.
- Type
list<string>- Since
- 1.5.0
- Reload
- hot
ai.backends.*.price
Price of a million tokens, in euros, input and output apart; 0 is a price. Required as soon as a budget is counted in euros (except a grpc backend or one metered upstream).
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.backends.*.price.input_per_mtok
Price in euros of a million input tokens. A non-negative number.
- Type
number- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
ai.backends.*.price.output_per_mtok
Price in euros of a million output tokens. A non-negative number.
- Type
number- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
ai.backends.*.tls
Client TLS toward the backend - a relay's mutual TLS -, as an upstream's. Only used with an https:// URL.
- Type
object- Since
- 1.5.0
- Reload
- hot
ai.backends.*.tls.ca_file
PEM file of the authorities that verify the backend's certificate. Absent: the system's authorities.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.tls.cert_file
PEM client certificate presented to the backend; goes with key_file.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.tls.key_file
PEM private key of the client certificate; goes with cert_file.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.tls.server_name
Name expected in the backend's certificate (SNI), when it differs from the URL's host.
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.upstream
For a grpc backend only, and required there: name of an upstream with protocol: grpc that serves its methods. Such a backend carries no url, model, authentication nor price: its methods' (x-flexway-ai).
- Type
string- Since
- 1.5.0
- Reload
- hot
ai.backends.*.url
The backend's address: an absolute http or https URL (for instance https://api.provider.example/v1). Required, except for a grpc backend.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.budget
The per-tenant inference budget, counted in a Redis-compatible shared cache (Redis, Dragonfly or Valkey) every replica uses.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.budget.daily_tokens
Tokens per tenant and UTC day. A non-negative integer; 0: no daily budget.
- Type
integer- Since
- 0.1.0
- Reload
- hot
ai.budget.monthly_eur
Per-tenant budget in euros over the calendar month, at each backend's declared price. A non-negative number; 0: none. Requires price on the backends.
- Type
number- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
ai.budget.monthly_tokens
Tokens per tenant and UTC calendar month. A non-negative integer; 0: no monthly budget.
- Type
integer- Since
- 0.1.0
- Reload
- hot
ai.budget.soft
Soft cap: past at of the euro budget, the gateway warns (Flexway-Budget: soft, a metric, a log line) and routes to backend when set. Requires a euro budget (monthly_eur, or an override's).
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.budget.soft.at
Share of the euro budget past which the soft cap applies: a number in (0, 1] (for instance 0.8).
- Type
number- Bounds
- value ≥ 0, ≤ 1
- Since
- 0.1.0
- Reload
- hot
ai.budget.soft.backend
Backend of ai.backends to switch to past the soft cap - except a sensitive request, which stays pinned. Never a grpc backend. Absent: warn only.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.budget.store
Shared cache of the budget counters: redis://host:port (or rediss://), or a reference (${VAR}, file:/path) as soon as it carries a password. Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.default_backend
Backend of ai.backends that serves a call no override routes elsewhere. Required; an openai or relay backend, never grpc.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.overrides
Route or budget one tenant, or one agent of it, differently; the first match wins. An override that names a capability only routes, never budgets.
- Type
list<object>- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.backend
Backend of ai.backends that serves the matching calls; never a grpc backend. Required when match.capability is set, and that backend must serve the capability.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.daily_tokens
Daily token budget of the matching tenant, in place of ai.budget.daily_tokens. A non-negative integer; refused with match.capability.
- Type
integer- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.match
What selects the calls: a tenant, an agent of it, a capability.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.match.agent
Calling agent (the call's subject) the override applies to, within tenant.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.match.capability
Capability asked for: chat, vision or embeddings. Such an override only routes: it requires backend and refuses any budget.
- Type
string- Allowed values
chatvisionembeddings- Since
- 1.5.0
- Reload
- hot
ai.overrides.*.monthly_eur
Monthly euro budget of the matching tenant, in place of ai.budget.monthly_eur. A non-negative number; requires price on the backends; refused with match.capability.
- Type
number- Since
- 0.1.0
- Reload
- hot
ai.overrides.*.monthly_tokens
Monthly token budget of the matching tenant, in place of ai.budget.monthly_tokens. A non-negative integer; refused with match.capability.
- Type
integer- Since
- 0.1.0
- Reload
- hot
ai.security
Identities /v1/* accepts, any one of which suffices - as security does in a contract. A non-empty list; each entry names exactly one mechanism: trusted_headers, oidc, api_key or mtls.
- Type
list<object>- Since
- 0.1.0
- Reload
- hot
ai.security.*.mtls
Accepts a declared client certificate ({}). Requires auth.mtls.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.security.*.oidc
Accepts a token from an issuer of auth.issuers, with the scopes and roles required. Requires at least one issuer.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.security.*.oidc.roles
Roles the token must carry (read through its issuer's roles_claim).
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
ai.security.*.trusted_headers
Accepts the identity a trusted peer wrote into the headers of auth.trusted_headers ({}), believed from a peer of server.trusted_proxies only. Requires auth.trusted_headers.
- Type
object- Since
- 0.1.0
- Reload
- hot
ai.sensitive_backend
Internal backend of ai.backends a sensitive request is pinned to. An external or grpc backend is refused; without one, a sensitive request is refused (403), never sent to an external backend.
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.sensitive_header
Header that, set to true by a caller, pins the request to sensitive_backend. Believed from any caller: it can only make routing stricter. A header name (letters, digits, -).
- Type
string- Since
- 0.1.0
- Reload
- hot
ai.vision
Bounds of the images of a chat completion. Absent: the defaults, and only inline data: images are accepted.
- Type
object- Since
- 1.5.0
- Reload
- hot
ai.vision.allowed_origins
Origins (https://host[:port], no path) an image may be given by URL from. Empty: inline data: images only. The gateway never fetches them: the backend does.
- Type
list<string>- Since
- 1.5.0
- Reload
- hot
ai.vision.max_body_bytes
Bound of the body of a chat completion that carries images. A size (24MiB, or a number of bytes); default 24MiB. A completion without image keeps server.limits.max_body. At least max_image_bytes.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.5.0
- Reload
- hot
ai.vision.max_image_bytes
Bound of one image, decoded. A size (8MiB, or a number of bytes); default 8MiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.5.0
- Reload
- hot
audit
Chained audit stream of the API plane's authorization decisions: each entry is linked to the previous one by a hash, so a rewrite shows.
- Type
object- Since
- 1.0.0
- Reload
- hot
audit.decisions
Which decisions are recorded: all (every one) or refusals (refusals only). Absent or empty: no decision is recorded.
- Type
string- Allowed values
allrefusals- Since
- 1.0.0
- Reload
- hot
audit.keyrestart
HMAC key of the chain and of the subject's digest, by reference (${VAR} or file:/path), never a literal. Without it, whoever can write the whole stream can rewrite it and recompute every hash. Read once at start.
- Type
string- Since
- 1.0.0
- Reload
- restart required
auth
How an identity is verified - never what an operation requires, which the contract declares (security): token issuers, API keys, client certificates, trusted headers.
- Type
object- Since
- 0.3.0
- Reload
- hot
auth.api_keys
Callers' API keys, an identity - never an authorization: what an operation requires stays in the contract (an apiKey scheme). A key satisfies only the alternative that names it and opens only its bound operations.
- Type
object- Since
- 0.1.0
- Reload
- hot
auth.api_keys.storerequired
File of the keys' digests: file: followed by a path, relative to the configuration file unless absolute, mounted from a secret. Never a key in clear; read again at each reload - removing an entry revokes the key.
- Type
string- Pattern
^file:.+- Since
- 0.1.0
- Reload
- hot
auth.issuers
Trusted token providers (OIDC), several at once: a customer usually has one for its employees and another for its end users. Two entries may not name the same issuer.
- Type
list<object>- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.algorithms
Signature algorithms accepted. Default: the asymmetric family (RS256 to RS512, PS256 to PS512, ES256 to ES512, EdDSA). none and the HMAC family (HS*) are refused at load.
- Type
list<string>- Default
["RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512","EdDSA"]- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.audience
Audience a token must be issued for, checked together with the issuer. Required unless audiences is used; exclusive with audiences.
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.audiences
Instead of audience, accepts a token issued for any one of them - while an API renames its audience. No empty entry; exclusive with audience.
- Type
list<string>- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.client
The gateway's own client at this issuer: to exchange a caller's token for one issued to an upstream (RFC 8693), introspect opaque or delegated tokens, obtain a discovery token. Required as soon as an upstream declares token_exchange or agents.delegation is set.
- Type
object- Since
- 0.1.0
- Reload
- hot
auth.issuers.*.client.idrequired
The gateway's client id at the issuer. Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.issuers.*.client.secretrequiredsecret
The client secret, by reference (${VAR} or file:/path), resolved at each use: a rotation is read without a reload. Never a value in clear.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 0.1.0
- Reload
- hot
auth.issuers.*.discoveryrequired
URL of the provider's discovery document, ending with /.well-known/openid-configuration. An absolute http(s) URL; required. The issuer identifier is derived from it, unless issuer gives it.
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.issuer
Identifier the provider states, when it differs from the discovery URL - a provider reached internally by one name and announcing its public one (split horizon). An absolute http(s) URL; the discovery document and every token must state exactly this value. Absent: derived from discovery.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.issuers.*.namerequired
Name of the issuer in logs and metrics, unique. Required; apikey and mtls are reserved.
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.opaque_tokens
Makes this issuer the one that answers for tokens that are not JWTs: they are introspected (RFC 7662) with client, then required. At most one issuer: an opaque token names no issuer.
- Type
object- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.opaque_tokens.cache
How long an introspection answer is reused - the delay before a revocation is seen -, never past the token's exp. A duration from 1s to 5m; default 30s.
- Type
string- Default
30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.roles_claim
Dotted path of the claim holding the roles (realm_access.roles for Keycloak, roles for Entra ID). Absent: no role can be satisfied for this issuer.
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.scopes_claim
Claim holding the scopes. Default scope (space-separated), then scp.
- Type
string- Default
scope- Since
- 0.3.0
- Reload
- hot
auth.issuers.*.service_accounts
How this provider marks a token issued to a client acting for itself, when its subject is not the client id (Keycloak: preferred_username = service-account-<client>). claim and prefix are required.
- Type
object- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.service_accounts.claimrequired
Claim that marks a service account (for instance preferred_username). Required.
- Type
string- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.service_accounts.prefixrequired
Prefix of the claim value that marks a service account, followed by the client id (for instance service-account-). Required and non-empty: an empty prefix would mark every token.
- Type
string- Since
- 1.0.0
- Reload
- hot
auth.issuers.*.tenant_claim
Name of the claim holding the tenant. Absent: requests from this issuer carry none.
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.mtls
Client certificates the gateway recognizes - an identity, required by a contract's mutualTLS scheme. Verified by the TLS listener (server.tls) or attested by a trusted edge's x-forwarded-client-cert header.
- Type
object- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients
Recognized certificates, each bound to a tenant and to operations.
- Type
list<object>- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients.*.idrequired
Name of the certificate in logs and metrics, unique. Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients.*.operations
Operation ids (operationId) this certificate opens - those only. Required and non-empty.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients.*.subject
The certificate's Subject (for instance CN=batch,O=Acme). Exactly one of uri or subject.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients.*.tenantrequired
Tenant the certificate is bound to. Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.mtls.clients.*.uri
The certificate's first URI SAN (a SPIFFE id, for instance spiffe://bank.example/settler). Exactly one of uri or subject.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.tenant_header
Header the resolved tenant is written to, toward the upstream; whatever a caller sent under that name is overwritten. A header name (letters, digits, -). Empty: the tenant is not propagated (it is still a metric dimension).
- Type
string- Since
- 0.3.0
- Reload
- hot
auth.trusted_headers
Headers a trusted peer - a mesh ingress that authenticated the caller - writes the identity into. Believed from a peer of server.trusted_proxies only, then required; refused with server.peer_identity_header. The names are the deployment's.
- Type
object- Since
- 0.1.0
- Reload
- hot
auth.trusted_headers.subject
Name of the header carrying the subject (the calling agent). Optional; a header name.
- Type
string- Since
- 0.1.0
- Reload
- hot
auth.trusted_headers.tenant
Name of the header carrying the tenant. Required; a header name (letters, digits, -).
- Type
string- Since
- 0.1.0
- Reload
- hot
contracts
The files that carry the served set: the contract is the configuration. At least one contract is required (openapi, protobuf, a2a or asyncapi), except for a gateway that serves the inference surface (ai) alone. Paths are relative to the configuration file, read from disk at load, with no network access.
- Type
object- Since
- 0.1.0
- Reload
- hot
contracts.a2a
Declared A2A agent cards (JSON files, .json): each method of an agent is an operation, served at the addresses its card declares and relayed to the upstream its x-flexway-a2a names. Each entry once, never empty.
- Type
list<string>- Since
- 1.2.0
- Reload
- hot
contracts.asyncapi
AsyncAPI 3 document (.yaml, .yml or .json): its send and receive operations are the asynchronous plane - publications reached through OpenAPI operations marked x-flexway-publish, consumptions through x-flexway-subscribe, webhook deliveries declared with x-flexway-deliver.
- Type
string- Since
- 1.5.0
- Reload
- hot
contracts.openapi
Default OpenAPI contract: served on every host that declares no contracts of its own, and on any host not declared at all. Optional once some host declares its own.
- Type
string- Since
- 0.1.0
- Reload
- hot
contracts.protobuf
Protobuf descriptor sets (FileDescriptorSet, imports included - buf build, or protoc with its imports), with extension .binpb, .pb or .protoset, served beside the OpenAPI on the same hosts: every method of every service they declare is an operation.
- Type
list<string>- Since
- 1.1.0
- Reload
- hot
errors
Shape of the RFC 9457 problem documents of the product routes. The inference surface /v1/* keeps the OpenAI envelope.
- Type
object- Since
- 1.0.0
- Reload
- hot
errors.field_codes
Renames the code of a field error (errors[].code of a 422 answer): a JSON Schema keyword a request can break (required, type, enum, pattern, minLength...) or invalid, to the operator's own token (letters, digits, _ . -, 64 at most). A keyword not listed keeps its name.
- Type
map<string>- Since
- 1.0.0
- Reload
- hot
errors.type_base
Namespace of the problems' type: an absolute http(s) URL ending with /, to which the code is appended - the operator's portal rather than the product's. Absent: the product's default namespace.
- Type
string- Since
- 1.0.0
- Reload
- hot
hosts
The hosts served, by name (the request's authority): each groups the operations served under that name and gives them a default upstream.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
hosts.*.contracts
OpenAPI contracts this host serves - exactly their union, nothing of the default contract. Paths relative to the configuration file, each listed once. Absent: the default contract (contracts.openapi).
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
hosts.*.default_upstream
Upstream (a name declared in upstreams) of this host's operations that name none with x-flexway-upstream.
- Type
string- Since
- 0.1.0
- Reload
- hot
hosts.*.validation
How much of a request is validated against the contract on this host: full (default, everything), params (parameters only, the body is relayed unread and the service validates it) or off. An operation's own x-flexway-validation overrides it.
- Type
string- Allowed values
fullparamsoff- Default
full- Since
- 1.0.0
- Reload
- hot
kms
The key management service of field-level encryption on the Kafka listener: it wraps the data keys the gateway draws, under a key that never leaves it. Exactly one kind is written: vault_transit, aws_kms, gcp_kms or local; absent, a contract that declares x-flexway-encrypt is refused at load.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.aws_kms
AWS KMS. Without credentials_file, credentials come from the SDK's default chain (IRSA, instance role).
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.aws_kms.credentials_filesecret
Path of a mounted AWS shared credentials file (never a value); the file must exist. Absent: the SDK's default chain.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
kms.aws_kms.endpoint
An https:// URL of a KMS endpoint other than the region's (private endpoint, emulator). Absent: the region's public endpoint.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.aws_kms.profile
The profile to read in credentials_file; refused when credentials_file is not written.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.aws_kms.regionrequired
The AWS region of the key (eu-west-3); required.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.cache
Bounds the data keys kept unwrapped in memory: by number, by time, and how long a KMS refusal is remembered.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.cache.max_keys
Number of data keys kept unwrapped, shared between tenants; from 1 to 1,000,000, default 10000.
- Type
integer- Default
10000- Bounds
- value ≥ 1, ≤ 1000000
- Since
- 1.6.0
- Reload
- hot
kms.cache.negative_ttl
How long a KMS refusal is remembered before asking again; from 100ms to 5m, default 5s. A key erasure takes effect within ttl + negative_ttl.
- Type
string- Default
5s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
kms.cache.ttl
Lifetime of an unwrapped data key in memory, counted from its unwrapping; the writing key is checked again with the KMS every ttl. From 1s to 24h, default 1h.
- Type
string- Default
1h- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
kms.gcp_kms
Google Cloud KMS. Without credentials_file, Application Default Credentials (Workload Identity).
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.gcp_kms.credentials_filesecret
Path of a mounted service account key (never a value); the file must exist. Absent: Application Default Credentials.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
kms.gcp_kms.endpoint
A Cloud KMS endpoint other than the public one; absent: cloudkms.googleapis.com.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.keyrequired
The KMS key that wraps the data keys: a Vault transit key, an AWS key id, ARN or alias, a resource name projects/<p>/locations/<l>/keyRings/<r>/cryptoKeys/<k> for GCP, a key file for local. {tenant} makes it one key per tenant (destroying it erases that tenant's fields alone). Letters, digits and . _ : / @ + = , -; a Vault or local key is a single name, without / or :. Required, checked at start.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.local
Keys in files of a mounted directory: tests and development only.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.local.dirrequired
Directory of the key files; required, it must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.previous_keys
Former values of key a record may still name: read, never written; a record naming any other key is refused. Same syntax as key, {tenant} included; 8 at most, no duplicate nor key itself.
- Type
list<string>- Bounds
- items ≤ 8
- Since
- 1.6.0
- Reload
- hot
kms.rotation
When a new data key starts: after interval or max_encryptions encrypted fields, whichever comes first.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.rotation.interval
How long a data key is used before the next one; from 1m to 168h (7 days), default 1h.
- Type
string- Default
1h- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
kms.rotation.max_encryptions
Number of fields encrypted under one data key before the next; from 1 to 2^30 (1,073,741,824), default 5000000.
- Type
integer- Default
5000000- Bounds
- value ≥ 1, ≤ 1073741824
- Since
- 1.6.0
- Reload
- hot
kms.tenant_calls
Token bucket of the KMS calls one tenant's records cause: a producer that exhausts its own never touches another tenant's.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.tenant_calls.burst
KMS calls allowed at once for one tenant; at least 1, default 20.
- Type
integer- Default
20- Bounds
- value ≥ 1
- Since
- 1.6.0
- Reload
- hot
kms.tenant_calls.rate
KMS calls per second for one tenant; more than 0, default 10.
- Type
number- Default
10- Since
- 1.6.0
- Reload
- hot
kms.timeout
Timeout of one KMS call, which holds the Kafka request that needs it; more than 0 and 30s at most, default 2s. KMS unavailable: KAFKA_STORAGE_ERROR, never cleartext.
- Type
string- Default
2s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
kms.vault_transit
Vault's transit engine, with a derived key (its context binds tenant and topic). Authentication by token or by kubernetes, exactly one.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.addressrequired
Vault's absolute https:// URL (https://vault.security:8200), without credentials nor query; http:// is refused: the token would travel in clear. Required.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.kubernetes
Vault's Kubernetes auth method: the pod's service account token, for a role. Exclusive with token.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.kubernetes.mount
Path of the Kubernetes auth method in Vault; default kubernetes.
- Type
string- Default
kubernetes- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.kubernetes.rolerequired
The Vault role requested with the service account token; required.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.kubernetes.token_filesecret
File of the service account token; default /var/run/secrets/kubernetes.io/serviceaccount/token.
- Type
string- Default
/var/run/secrets/kubernetes.io/serviceaccount/token- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
kms.vault_transit.mount
Path of the transit engine in Vault; segments of letters, digits, ., _, - separated by /. Default transit.
- Type
string- Default
transit- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.namespace
Vault namespace (Vault Enterprise); optional.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tls
Client TLS toward Vault: trusted authority, client certificate, expected name.
- Type
object- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tls.ca_file
PEM file of the authority that verifies the server's certificate; absent: the system's authorities. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tls.cert_file
Client certificate (PEM) presented to Vault; goes with key_file. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tls.key_file
Private key (PEM) of the client certificate; goes with cert_file. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tls.server_name
Name expected in Vault's certificate, when it differs from the host of address.
- Type
string- Since
- 1.6.0
- Reload
- hot
kms.vault_transit.tokensecret
Vault token by reference, ${VAR} or file:/path, read at each call; never the value. Exclusive with kubernetes.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
listeners.kafka
The Kafka listener: Kafka producers, consumers and admin tools reach the virtual clusters the AsyncAPI contract declares (x-flexway-kafka-proxy), under the same decision as HTTP. Nothing here lists a topic: the contract does. One TLS port, the broker named by the client's SNI (address), or plaintext ports inside a mesh (plaintext); requires contracts.asyncapi.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.kafka.addressrestart
The TLS listener's host:port address (:9093); requires tls and sni_domain. Absent: plaintext ports only. Read once at start.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.advertised_portrestart
Port written into the broker addresses a client is given (Metadata, FindCoordinator): the one a load balancer exposes. From 1 to 65535; absent: the port of address. Only with address.
- Type
integer- Bounds
- value ≥ 1, ≤ 65535
- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.auth_timeout
Absolute time a connection has to authenticate; more than 0 and 1m at most, default 10s.
- Type
string- Default
10s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.idle_timeout
Closes a connection that sent nothing for this long (Kafka's connections.max.idle.ms); at least 1s, default 10m.
- Type
string- Default
10m- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_connection_rate_per_tenant
Connections one tenant opens per second, counted at authentication (a one-second bucket): a client reconnecting in a loop costs its own tenant's places, never the others'. From 0 (no bound) to 100000, default 100.
- Type
number- Default
100- Bounds
- value ≥ 0, ≤ 100000
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_connectionsrestart
Client connections open at once; past it, a new one waits to be accepted. From 1 to 100000, default 4096.
- Type
integer- Default
4096- Bounds
- value ≥ 1, ≤ 100000
- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.max_connections_per_ip
Connections of one client address; from 0 (no bound, behind a proxy that hides the addresses) to max_connections, default 16.
- Type
integer- Default
16- Bounds
- value ≥ 0
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_connections_per_tenant
Connections of one tenant, counted at authentication; from 1 to max_connections, default 1024.
- Type
integer- Default
1024- Bounds
- value ≥ 1
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_fetch_wait
Longest a Fetch may wait at the broker for data (its max_wait_ms); from 100ms to 5m, default 30s.
- Type
string- Default
30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_in_flight_bytes
Answers one connection holds in memory, read from the broker and not yet written; past it, the listener stops reading the broker (backpressure, never a refusal). A size (64MiB) from 1MiB to max_total_in_flight_bytes, default 64MiB.
- Type
integer | string- Default
64MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_request_bytes
Largest request frame of an authenticated client, read whole before it is decoded; from 64KiB to 100MiB, default 16MiB. Before authentication, 64 KiB only.
- Type
integer | string- Default
16MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_response_bytes
Largest broker response; a Fetch's MaxBytes is held below half of it. From 1MiB to 256MiB, default 64MiB; with encrypted fields, at least max_request_bytes.
- Type
integer | string- Default
64MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_session_lifetime
Longest session whatever the credential: a SASL client re-authenticates before it (KIP-368), a connection identified by its certificate is closed; a revocation is seen at the latest then. From 1m to 24h, default 1h.
- Type
string- Default
1h- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_tenant_in_flight_bytesrestart
The same bound as max_in_flight_bytes, for every connection of one tenant: its share of max_total_in_flight_bytes; a tenant that does not read never stalls the others. From max_in_flight_bytes to max_total_in_flight_bytes; absent: an eighth of the total, at least max_in_flight_bytes. Read once at start.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.max_topic_partitions
Partitions an administrator may give a topic (CreateTopics, CreatePartitions); from 1 to 10000, default 64.
- Type
integer- Default
64- Bounds
- value ≥ 1, ≤ 10000
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.max_total_in_flight_bytesrestart
Answers held in memory by the whole replica, all connections together; 64GiB at most, default 1GiB. Read once at start.
- Type
integer | string- Default
1GiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.max_unauthenticated_connections
Connections that have not proved who they are yet; past it, a new one is closed at once and authenticated clients keep their places. From 1 to max_connections, default 256.
- Type
integer- Default
256- Bounds
- value ≥ 1
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.on_tenant_budget_exceeded
What happens to a connection whose answer would exceed max_tenant_in_flight_bytes: wait (default) - the broker is not read until the tenant's clients read - or close - the connection ends at once, for tenants not trusted to read. The other tenants are never stalled.
- Type
string- Allowed values
waitclose- Default
wait- Since
- 1.6.0
- Reload
- hot
listeners.kafka.plaintextrestart
Fallback without TLS: a bootstrap port and a port per broker for each virtual cluster, only where a mesh already encrypts between pods (mesh_only: true required). Read once at start.
- Type
object- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.advertised_hostrestart
Host written into the broker addresses a client is given: the gateway's Service name in the mesh, without a port. Required.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.clustersrestart
The ports of each virtual cluster, by cluster name (a DNS label: lower-case letters, digits, -); at least one.
- Type
map<object>- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.clusters.*.first_node_idrestart
Node id of the first broker: port from + 1 + i serves node first_node_id + i. A non-negative integer, default 0.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.clusters.*.portsrestart
Closed range of the cluster's ports: from is the bootstrap, then one port per broker up to to; 65 ports at most, never shared with another cluster nor with address.
- Type
object- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.clusters.*.ports.fromrestart
The cluster's bootstrap port; from 1 to 65535.
- Type
integer- Bounds
- value ≥ 1, ≤ 65535
- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.clusters.*.ports.torestart
Last port of the range, greater than from; 65535 at most.
- Type
integer- Bounds
- value ≥ 1, ≤ 65535
- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.plaintext.mesh_onlyrestart
Must be true: states that a mesh encrypts between pods. Without it, a Kafka client's credentials would cross the network in clear, and the configuration is refused.
- Type
boolean- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.quotas
Byte and request quotas per verified principal and per tenant, as a Kafka broker applies them (KIP-219): the answer leaves at once with throttle_time_ms, then the connection is not read for that long. Absent: nothing is throttled.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.client
Rates of each verified principal - the token's subject, the API key, the certificate -, never the client.id a client names itself with. No bound by default.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.client.consumer_byte_rate
Bytes read per second (Fetch answers) per principal; a size (10MiB), 0 or absent: no bound.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.client.producer_byte_rate
Bytes produced per second (Produce requests) per principal; a size (10MiB), 0 or absent: no bound.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.client.request_rate
Requests per second per principal, whatever the API; a non-negative number, 0 or absent: no bound.
- Type
number- Bounds
- value ≥ 0
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.max_throttle
Cap of the announced throttle_time_ms and of the silence that follows, below the clients' request.timeout.ms; from 100ms to 30s, default 10s.
- Type
string- Default
10s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.quota
Name of a policy of type quota in policies.definitions: the tenant's day or month budget of Produce requests, shared with HTTP under the same name; spent: POLICY_VIOLATION. Empty: none.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.tenant
Rates of every principal of one tenant together. No bound by default.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.tenant.consumer_byte_rate
Bytes read per second per tenant; a size, 0 or absent: no bound.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.tenant.producer_byte_rate
Bytes produced per second per tenant; a size, 0 or absent: no bound.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.tenant.request_rate
Requests per second per tenant, whatever the API; 0 or absent: no bound.
- Type
number- Bounds
- value ≥ 0
- Since
- 1.6.0
- Reload
- hot
listeners.kafka.quotas.window
How much of a rate a burst may take at once: a bucket holds rate x window; from 100ms to 10s, default 1s.
- Type
string- Default
1s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.kafka.sni_domainrestart
DNS domain the broker names live under (kafka.example.com): bootstrap.<cluster>.<sni_domain> and broker-<id>.<cluster>.<sni_domain>. At least two labels, lower-case; required with address.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.tlsrestart
Certificate of the TLS listener - one covering *.<cluster>.<sni_domain> for every cluster - and, with client_ca_file, the authority of client certificates. Required with address, refused without it.
- Type
object- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.tls.cert_filerestart
The listener's certificate (PEM); required, the file must exist.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.tls.client_ca_filerestart
PEM authority client certificates are verified against (the X509 identity); optional, the file must exist.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.kafka.tls.key_filerestart
Private key (PEM) of the listener's certificate; required, the file must exist.
- Type
string- Since
- 1.6.0
- Reload
- restart required
listeners.mqtt
The MQTT device listener: devices connect in MQTT 5 or 3.1.1 over TCP, TLS or WebSocket and reach the customer's broker through it, one broker connection per device, every packet under the same decision as HTTP. Nothing here lists a topic: the AsyncAPI contract does (x-flexway-device). Requires contracts.asyncapi.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.address
The listener's host:port address (:8883); TLS when tls is set. Read once at start.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.advertised_address
The host:port devices reach the listener at - the load balancer's: the default failover.server_reference.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.allow_zero_keepalive
Admits an MQTT 3.1.1 device asking no keep-alive (0). false (the default): it is refused (return code 0x05), like one asking more than max_keepalive - MQTT 3.1.1 cannot be told a keep-alive, and a silent device would never be seen gone. MQTT 5 is told max_keepalive instead.
- Type
boolean- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.broker_mesh_only
Admits brokers in clear (mqtt://, ws://) when the listener itself is in TLS: the mesh encrypts the hop to the broker. false (the default): a broker in clear is refused at load unless mesh_only is set.
- Type
boolean- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.connect_timeout
Time a connection has to complete TLS and send its CONNECT, and the broker to answer; more than 0 and 1m at most, default 5s.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device
Bounds of each device connection; an operation's x-flexway-device overrides its rates.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.burst
Seconds of each rate a burst may take at once; from 1 to 60, default 2.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.bytes_per_second
PUBLISH payload bytes a device sends per second, under the same backpressure. 0: none. Default 512 KiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.connect_rate_per_identity
CONNECT of one identity per second; past it 0x9F: a device that reconnects in a loop never evicts itself again and again. 0: none. Default 1.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_correlation_data_bytes
Bytes of a PUBLISH's correlation data; past it 0x95. Default 8 KiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_filters_per_subscribe
Filters of one SUBSCRIBE; past it each is refused 0x97. Default 10.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_refusals_per_minute
Refused packets of one connection in a minute: each refusal spends the device's message rate, its audit is sampled (one entry a second per cause), and past this count the device is disconnected 0x96. 0: no bound. From 0 to 100000, default 60.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_sessions_per_identity
Connections one identity holds at once on a replica with sessions: per_client_id; past it a new one is refused 0x97 (3.1.1: 0x03). From 1 to max_connections, default 10 (or max_connections if lower).
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_subscriptions
Subscriptions of a device; past it a filter is refused 0x97 (3.1.1 0x80). Default 50.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.max_user_properties_bytes
Bytes of the user properties of a packet; past it 0x95. Default 8 KiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.messages_per_second
PUBLISH a device sends per second; past it the listener stops reading the device (backpressure, never a refusal) and keeps its broker connection alive meanwhile. 0: none. Default 100.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.receive_maximum
QoS 1 and 2 PUBLISH in flight from a device, announced as the lower of it and the broker's; past it 0x93. Default 100.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.device.sessions
Sessions of one identity: single (the default) - client id <tenant>/<identity> at the broker, a second connection evicts the first (0x8E) -, or per_client_id - <tenant>/<identity>/<the device's client id>, for an identity several devices share.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover
Moves the devices of a replica that drains or is full to another one: MQTT 5 is told where to go, 3.1.1 reconnects through the load balancer.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.handover_timeout
Time a draining replica holds a device's broker connection for it to come back elsewhere; past it the connection closes with the will. From 0s to 10m, default 30s.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.mode
redirect (the default): 0x9C (or 0x9D) and a Server Reference, the broker connection held handover_timeout for the device to come back through another replica; off: a drain sends 0x8B and closes the broker connection with the will.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.reason
use_another_server (0x9C, temporary, the default) or server_moved (0x9D, permanent).
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.redirect_above
Share of max_connections, in percent, past which a CONNECT is redirected rather than accepted. Default 95.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.server_reference
Where a redirected device goes; default advertised_address - a client that ignores it reconnects to the same place anyway.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.failover.will_delay_on_handover
Toward an MQTT 5 broker, a will that declares no Will Delay Interval is written with one equal to handover_timeout, and the broker session's expiry raised to cover it: the will survives a takeover by another replica. The cost: the will of a device really lost goes up to handover_timeout later. No effect on an MQTT 3.1.1 device. Default false.
- Type
boolean- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_connection_rate_per_ip
New connections of one client address per second; 0: none. Default 20.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_connection_rate_per_tenant
New device connections of one tenant per second; past it 0x9F (3.1.1 0x03). 0: none. Default 100.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_connections
Device connections of a replica; past it a CONNECT is refused 0x97 (3.1.1 0x03). From 1 to 1000000, default 50000. Read once at start.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_connections_per_ip
Connections of one client address; 0: none - set it behind a load balancer or proxy that hides the devices' addresses (the chart keeps them with externalTrafficPolicy: Local), or every device shares one address and one bound. Default 64.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_connections_per_tenant
Device connections of one tenant on a replica; past it 0x97. Default 10000.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_keepalive
Highest keep-alive a device gets: an MQTT 5 device asking more (or none) is told this one (Server Keep Alive); an MQTT 3.1.1 device asking more is refused (0x05), none too unless allow_zero_keepalive. From 1s to 65535s, default 1200s.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_packet_bytes
Bound of a packet, read whole before it is decoded; announced to an MQTT 5 device as the lower of it and the broker's Maximum Packet Size. From 1 KiB to 256 MiB, default 256 KiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_session_expiry
Highest session expiry a device's session gets at the broker. Default 1h.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_session_lifetime
Longest device connection whatever its credential: past it the device is disconnected and reconnects with a credential checked again. From 1m to 30d, default 24h.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.max_unauthenticated_connections
Connections that have not sent their CONNECT yet; past it a new one is closed at once. From 1 to max_connections, default 1024.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.mesh_only
Admits the listener without TLS: a device's token or key crosses the network in clear, so it is written only where a mesh encrypts between pods. Refused with tls. Default false.
- Type
boolean- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.tenant.bytes_per_second
PUBLISH payload bytes of every device of a tenant per second, under backpressure. 0: none. Default 20 MiB.
- Type
integer | string- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.tenant.messages_per_second
PUBLISH of every device of a tenant per second, under backpressure. 0: none. Default 5000.
- Type
number- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.tenant.quota
Names a policy of type quota: the tenant's day and month budget of PUBLISH, shared with HTTP under that name. Spent: PUBACK 0x97, QoS 0 dropped and counted, 3.1.1 closed. Absent: none.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.tls
The listener's certificate and, with client_ca_file, the authority device certificates are verified against (required by an X509 alternative). Required unless mesh_only. Read once at start.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.tls.client_ca_file
Path of the authority device certificates are verified against; absent: no device certificate is verified.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.topic_alias_maximum
Topic aliases an MQTT 5 device may use toward the listener; an alias is recorded only once its topic is granted, never relayed. 0: none. At most 1000, default 10.
- Type
integer- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.websocket
MQTT over WebSocket (subprotocol mqtt) on an address of its own, with the listener's TLS. Read once at start.
- Type
object- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.websocket.address
The WebSocket listener's host:port (:8884), not the listener's.
- Type
string- Since
- 1.6.0
- Reload
- hot
listeners.mqtt.websocket.path
The HTTP path of the WebSocket; default /mqtt.
- Type
string- Since
- 1.6.0
- Reload
- hot
observability
The gateway's traces, logs and measurements. Without a collector the gateway still starts: a valid configuration, not a degraded one; /metrics stays served.
- Type
object- Since
- 0.2.0
- Reload
- hot
observability.access_log
Writes one line per finished request, with the path template - never the path received. Default false.
- Type
boolean- Since
- 1.0.0
- Reload
- hot
observability.kafka
Measurements of the Kafka listener beyond its fixed instruments.
- Type
object- Since
- 1.6.0
- Reload
- hot
observability.kafka.budget_wait_bucketsrestart
Boundaries of the flexway.kafka.tenant_budget.wait histogram (a tenant's wait for its share of in-flight bytes): strictly increasing positive durations, 20 at most; default 1 ms to 30 s. Read once at start.
- Type
list<string>- Default
["1ms","5ms","10ms","50ms","100ms","500ms","1s","5s","10s","30s"]- Bounds
- items ≤ 20
- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- restart required
observability.kafka.closures
Counts the normal closures of Kafka connections (flexway.kafka.connections.closed). Default true.
- Type
boolean- Default
true- Since
- 1.6.0
- Reload
- hot
observability.log_level
Least severe level written to the logs: debug, info (default), warn, error or fatal. Changes without a restart, for instance debug for the time of a diagnosis.
- Type
string- Allowed values
debuginfowarnerrorfatal- Default
info- Since
- 1.1.0
- Reload
- hot
observability.mqtt
Measurements of the MQTT device listener beyond its fixed instruments.
- Type
object- Since
- 0.2.0
- Reload
- hot
observability.mqtt.closures
Counts the normal closures of device connections (flexway.mqtt.connections.closed). Default true.
- Type
boolean- Since
- 0.2.0
- Reload
- hot
observability.otlp_endpointrestart
OTLP collector of the traces (host:port, for instance tempo.observ:4317); takes precedence over OTEL_EXPORTER_OTLP_ENDPOINT. Empty: no trace export. Read once at start.
- Type
string- Since
- 0.2.0
- Reload
- restart required
observability.samplingrestart
Trace sampling cap. Absent: every trace is kept. Read once at start.
- Type
object- Since
- 1.0.0
- Reload
- restart required
observability.sampling.max_per_secondrestart
New root traces kept per second and per replica, a positive number; 0: no cap.
- Type
number- Bounds
- value ≥ 0
- Since
- 1.0.0
- Reload
- restart required
observability.sparkplug
The table of Sparkplug B edge nodes each replica keeps for the nodes that cross it (GET /sparkplug/nodes, the console's Devices screen). Reloadable.
- Type
object- Since
- 0.2.0
- Reload
- hot
observability.sparkplug.max_devices_per_node
Devices (DBIRTH, DDEATH) kept for one node, 1 to 10000; past it the list is said truncated. Default 1000.
- Type
integer- Default
1000- Since
- 0.2.0
- Reload
- hot
observability.sparkplug.max_nodes
Nodes and host applications kept per replica, 1 to 50000 (a node is a connection). Full, the table first forgets an unknown node, then the oldest offline one; full of online nodes, a new one is not kept and is counted. Default 10000.
- Type
integer- Default
10000- Since
- 0.2.0
- Reload
- hot
observability.sparkplug.max_nodes_per_tenant
Nodes of one tenant kept per replica, 1 to max_nodes: a tenant never fills the others' table; at its bound the table first forgets one of its unknown nodes, then its oldest offline one; full of online nodes, a new one is not kept and is counted. Default 1000 (or max_nodes when lower).
- Type
integer- Default
1000- Since
- 0.2.0
- Reload
- hot
observability.sparkplug.offline_retention
How long a node offline, moved to another replica or seen only through its commands stays in the table, 1m to 720h. Default 24h.
- Type
string- Default
24h- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
policies
The policy model: named, reusable definitions, attached by chains. Effective chain global -> host -> routes -> operation; the operation adds its own with x-flexway-policies in the contract.
- Type
object- Since
- 0.1.0
- Reload
- hot
policies.chains
Attaches policies, from the broadest to the most precise: global, per host, per route motif. A name prefixed with ! removes a policy a broader level brought.
- Type
object- Since
- 0.1.0
- Reload
- hot
policies.chains.global
Policies applied to every request, by definition name.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
policies.chains.hosts
Policies per host: host name -> list of definition names.
- Type
map<list<string>>- Since
- 0.1.0
- Reload
- hot
policies.chains.routes
Policies per route motif: a path template starting with /, where * is one segment and ** any number ("/orders/**") -> list of definition names.
- Type
map<list<string>>- Since
- 0.1.0
- Reload
- hot
policies.definitions
The named policies: name -> definition (type, phase, when, config). Only the policies a chain or x-flexway-policies attaches apply.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
policies.definitions.*.config
The type's own configuration, decoded strictly against that type's schema (see the policy types): an unknown key is refused.
- Type
any- Since
- 0.1.0
- Reload
- hot
policies.definitions.*.phase
When the policy acts: request, response or error, among the phases its type accepts. Absent: the type's first phase.
- Type
string- Allowed values
requestresponseerror- Since
- 0.1.0
- Reload
- hot
policies.definitions.*.typerequired
The policy's type, from the catalogue: cors, rate-limit, quota, cache, header-inject, header-remove, rewrite-path, query-inject, query-remove, transform-body, redact, map-status, external-call. Required.
- Type
string- Allowed values
cachecorsexternal-callheader-injectheader-removemap-statusquery-injectquery-removequotarate-limitredactrewrite-pathtransform-body- Since
- 0.1.0
- Reload
- hot
policies.definitions.*.when
CEL condition compiled at load (has(auth.subject)): the policy applies only when it holds. Refused for cors, rate-limit and quota, which are attached where they apply instead.
- Type
string- Since
- 0.1.0
- Reload
- hot
policies.fragments
Imported policy fragments (1.7.0): import name -> file pinned by its digest. A fragment's definitions are named <import>/<name> here; the ones it enforces run at the head of every chain of the HTTP listener, before global, and are neither removed, replaced nor undone locally. Read from mounted files only, never from the network; YAML anchors, aliases and merge keys refused here. Absent: no fragment, the behaviour of 1.6.0. The import name: lower-case letters, digits and -, 63 at most.
- Type
map<object>- Since
- 1.7.0
- Reload
- hot
policies.fragments.*.digestrequired
The digest that pins the file: sha256: followed by the 64 hex characters of the sha256 of its bytes, with no canonical form - what sha256sum and flexway fragment digest print. Required. Different from the digest read: refused, naming the import, the expected and the read digest.
- Type
string- Pattern
^sha256:[0-9a-f]{64}$- Since
- 1.7.0
- Reload
- hot
policies.fragments.*.pathrequired
The fragment file (kind: PolicyFragment), relative to flexway.yaml, in its directory or below (.. and an absolute path outside that directory refused); a regular file of 1 MiB at most. Required. Read again at every reload: a file missing, or changed without its digest, refuses the load, and the configuration in force keeps serving.
- Type
string- Since
- 1.7.0
- Reload
- hot
policies.fragments.*.verify
Reserved for verifying a signature of the fragment, which is not built in this version: declared, it refuses the load rather than being ignored. The digest alone pins the file.
- Type
object- Since
- 1.7.0
- Reload
- hot
policies.fragments.*.verify.bundle
Reserved: the fragment's signature bundle. Not built in this version - refused at load.
- Type
string- Since
- 1.7.0
- Reload
- hot
policies.fragments.*.verify.key
Reserved: the public key that verifies the signature. Not built in this version - refused at load.
- Type
string- Since
- 1.7.0
- Reload
- hot
schema_registry
The schema registry binary payloads are read under: the Confluent API, served by Confluent, Apicurio, Karapace and Redpanda. Read, never written. Absent: a message that declares the registry's wire format is refused at load.
- Type
object- Since
- 1.6.0
- Reload
- hot
schema_registry.auth
How the gateway authenticates to the registry: username and password (HTTP Basic, Confluent Cloud's key and secret), or token - not both. Refused when url is http://.
- Type
object- Since
- 1.6.0
- Reload
- hot
schema_registry.auth.passwordsecret
Password by reference, ${VAR} or file:/path, read at each request; goes with username.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
schema_registry.auth.tokensecret
Bearer token by reference, ${VAR} or file:/path; exclusive with username and password.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
schema_registry.circuit_breaker
The registry's circuit breaker, as an upstream's: open, a message that needs the registry is refused at once (503), never waited for. On by default.
- Type
object- Since
- 1.6.0
- Reload
- hot
schema_registry.circuit_breaker.cooldown
How long the open breaker rests before a trial call; default 5s.
- Type
string- Default
5s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
schema_registry.circuit_breaker.failure_ratio
Share of failures that opens the breaker, in (0, 1]; default 0.5.
- Type
number- Default
0.5- Bounds
- value ≥ 0, ≤ 1
- Since
- 1.6.0
- Reload
- hot
schema_registry.circuit_breaker.min_requests
Minimum calls in the window before the failure share counts; default 20.
- Type
integer- Default
20- Since
- 1.6.0
- Reload
- hot
schema_registry.circuit_breaker.window
Sliding window over which the failure share is measured; default 10s.
- Type
string- Default
10s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
schema_registry.max_schemas
Schemas kept in memory, by id, compiled once each; from 1 to 100000, default 1000.
- Type
integer- Default
1000- Bounds
- value ≥ 1, ≤ 100000
- Since
- 1.6.0
- Reload
- hot
schema_registry.timeout
Timeout of a registry lookup, which holds the message that needs it; more than 0 and 30s at most, default 2s.
- Type
string- Default
2s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.6.0
- Reload
- hot
schema_registry.tls
Client TLS toward the registry; only with an https:// url.
- Type
object- Since
- 1.6.0
- Reload
- hot
schema_registry.tls.ca_file
PEM file of the authority that verifies the server's certificate; absent: the system's authorities. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
schema_registry.tls.cert_file
Client certificate (PEM) presented to the registry; goes with key_file. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
schema_registry.tls.key_file
Private key (PEM) of the client certificate; goes with cert_file. The file must exist.
- Type
string- Since
- 1.6.0
- Reload
- hot
schema_registry.tls.server_name
Name expected in the registry's certificate, when it differs from the host of url.
- Type
string- Since
- 1.6.0
- Reload
- hot
schema_registry.urlrequired
The registry's absolute http(s):// base address, without credentials, query nor fragment (https://registry.internal:8081); required. With http://, neither tls nor auth.
- Type
string- Since
- 1.6.0
- Reload
- hot
server
How the gateway behaves toward its upstreams and during a shutdown, independently of any operation. Every key has a default: an empty server: section is valid.
- Type
object- Since
- 0.2.0
- Reload
- hot
server.body
Bounds of the response bodies the body policies read (transform-body, redact, map-status), for the operations that declare one only.
- Type
object- Since
- 1.2.0
- Reload
- hot
server.body.max_bytes
Largest response body read to be transformed, a size (1MiB, 512KiB or a number of bytes); default 1MiB. Past it: 502 response_too_large, never a truncated nor an untransformed body.
- Type
integer | string- Default
1MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.2.0
- Reload
- hot
server.body.validate_sample
Share of transformed responses checked against the contract's schema, between 0 and 1; default 0.01. A departure is counted and logged, never answered as an error; 0 checks none.
- Type
number- Default
0.01- Bounds
- value ≥ 0, ≤ 1
- Since
- 1.2.0
- Reload
- hot
server.cacherestart
Bounds of the response cache of the operations that declare one. Holds nothing while no operation declares a cache. Read once at start.
- Type
object- Since
- 1.2.0
- Reload
- restart required
server.cache.max_bytesrestart
Total memory of the cache per replica, a size; default 32MiB. Past it, the least recently used response is evicted.
- Type
integer | string- Default
32MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.2.0
- Reload
- restart required
server.cache.max_entry_bytesrestart
Largest response stored, a size; default 1MiB (at most max_bytes). A larger one is relayed, never kept.
- Type
integer | string- Default
1MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 1.2.0
- Reload
- restart required
server.countersrestart
Shares rate limits and quotas across replicas through a Redis-compatible shared cache (Redis, Dragonfly or Valkey), reconciled periodically. Absent: every counter is local to its replica, and no quota can be declared. Read once at start.
- Type
object- Since
- 1.0.0
- Reload
- restart required
server.counters.prefixrestart
Prefix of this deployment's keys in the shared cache: letters, digits and dashes; default flexway. Two deployments sharing a cache would otherwise count together.
- Type
string- Default
flexway- Since
- 1.0.0
- Reload
- restart required
server.counters.storerequiredrestart
Address of the shared cache: redis://host:port or rediss://, without a password, or a reference (${VAR}, file:/path) when it carries one. Required.
- Type
string- Since
- 1.0.0
- Reload
- restart required
server.counters.syncrestart
Reconciliation period with the shared cache, between 100ms and 1m; default 1s. It is the window by which a shared limit may be exceeded.
- Type
string- Default
1s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.0.0
- Reload
- restart required
server.in_flightrestart
Gate in front of the data plane: requests worked on at once, waiting for a slot, open connections; past it, 503 at once. Absent: derived from the container's memory limit when it has one. Read once at start.
- Type
object- Since
- 1.1.0
- Reload
- restart required
server.in_flight.connectionsrestart
Client connections open at once, per listener; past it, a new one waits in the kernel's accept queue. 0: no limit. Absent: derived from the memory limit (25 % of memory / 32 KiB).
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.1.0
- Reload
- restart required
server.in_flight.maxrestart
Requests in flight at once, streams included. 0: no limit. Absent: derived from the memory limit (50 % of memory / 128 KiB, at least 64), adapted to saturation.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.1.0
- Reload
- restart required
server.in_flight.queuerestart
Requests that may wait for a slot; default 0 (refused at once). Requires wait, and a non-zero max.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.1.0
- Reload
- restart required
server.in_flight.waitrestart
How long a queued request waits at most, 10s at most. Required with queue, refused without it.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.1.0
- Reload
- restart required
server.limits.max_body
Largest request body read - it is read only to be validated against the contract; a size, default 1MiB. Past it: 413. A body that is only relayed is never held, whatever its size.
- Type
integer | string- Default
1MiB- Bounds
- value ≥ 1
- Pattern
^\s*[1-9][0-9]*\s*(B|KiB|MiB|GiB)?\s*$- Since
- 0.1.0
- Reload
- hot
server.peer_identity_header
Header a local mesh proxy writes the peer's verified identity into (Linkerd: l5d-client-id), believed from peers of trusted_proxies only (required with it). Declares a mesh; incompatible with auth.trusted_headers.
- Type
string- Since
- 1.0.0
- Reload
- hot
server.reloadrestart
How the gateway notices a changed configuration. Read once at start.
- Type
object- Since
- 0.1.0
- Reload
- restart required
server.reload.intervalrestart
How often the configuration and its contracts are read again and compared by content; default 5s. "0s": never, SIGHUP alone reloads.
- Type
string- Default
5s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- restart required
server.sheddingrestart
Sheds a share of the traffic while the gateway itself is saturated. Absent: nothing is shed. Read once at start.
- Type
object- Since
- 1.0.0
- Reload
- restart required
server.shedding.targetrequiredrestart
Saturation above which the gateway sheds: the 99th percentile of the Go scheduler's latency (how long a runnable goroutine waits for a processor), between 1ms and 1s. Operations marked x-flexway-priority: critical are never shed.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.0.0
- Reload
- restart required
server.shutdownrestart
What happens between SIGTERM and exit. Read once at start.
- Type
object- Since
- 0.2.0
- Reload
- restart required
server.shutdown.drainrestart
Time in-flight requests and streams get to finish once new ones are refused; default 20s. Past it, the remaining connections are closed, and that is logged.
- Type
string- Default
20s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- restart required
server.shutdown.mqtt_drain_spreadrestart
Spreads the redirections of the MQTT listener's devices over the drain, no reconnection storm on the other replicas; capped at half of drain. From 0s to 10m, default 30s.
- Type
string- Default
30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- restart required
server.timeouts
Budgets of one relayed exchange, in layers. There is deliberately no single global timeout.
- Type
object- Since
- 0.2.0
- Reload
- hot
server.timeouts.connect
Time to establish a connection to an upstream, TLS handshake included. A duration (5s, 500ms); default 5s.
- Type
string- Default
5s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
server.timeouts.read
Silence tolerated between two bytes of an upstream response; it alone governs a stream. Default 60s.
- Type
string- Default
1m- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
server.timeouts.total
Budget of the whole exchange, retries included; a streamed response is exempt from it. Default 30s. Overridden by upstreams.*.timeout, then by x-flexway-timeout.
- Type
string- Default
30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
server.tlsrestart
The gateway terminates TLS itself, on a listener of its own, and asks for a client certificate, verified against client_ca_file when presented. Read once at start; the files are read again when they rotate.
- Type
object- Since
- 0.1.0
- Reload
- restart required
server.tls.cert_filerequiredrestart
Path of the TLS listener's certificate (PEM). Required.
- Type
string- Since
- 0.1.0
- Reload
- restart required
server.tls.client_ca_filerestart
Path of the authority (PEM) that verifies presented client certificates. Absent: no client certificate is verified.
- Type
string- Since
- 0.1.0
- Reload
- restart required
server.tls.key_filerequiredrestart
Path of the TLS listener's private key (PEM). Required.
- Type
string- Since
- 0.1.0
- Reload
- restart required
server.trusted_proxies
Peers (CIDR, for instance 10.0.0.0/8) whose X-Forwarded-For is believed - the edge; from anyone else the header is ignored. local names the pod's own addresses (a mesh proxy). None by default.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
upstreams
The upstreams, by name: where declared operations are relayed to, and the brokers and webhook targets of the asynchronous plane. At least one; the name ai is reserved for the inference surface.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
upstreams.*.allow_private
Webhook only: opens the private address ranges to the connection guard (and http://), refused by default. Default false.
- Type
boolean- Since
- 1.5.0
- Reload
- hot
upstreams.*.amqp1
AMQP 1.0 only (protocol: amqp, protocol_version: "1.0"): what the broker does beyond the standard.
- Type
object- Since
- 1.6.0
- Reload
- hot
upstreams.*.amqp1.broker
AMQP 1.0 broker: rabbitmq, artemis, solace, servicebus or generic (default). It says how a stream reads a channel without taking the messages of other consumers; servicebus and generic publish and deliver by webhook only.
- Type
string- Allowed values
rabbitmqartemissolaceservicebusgeneric- Default
generic- Since
- 1.6.0
- Reload
- hot
upstreams.*.brokers
Brokers only (kafka, amqp, mqtt, nats), required: bootstrap addresses. Kafka: host:port; AMQP and MQTT: an amqp:// or amqps://, mqtt:// or mqtts:// URL; NATS: nats:// or tls://. Never credentials in the address.
- Type
list<string>- Since
- 1.5.0
- Reload
- hot
upstreams.*.circuit_breaker
The upstream's circuit breaker, always on: it opens when too many calls fail, refuses at once while resting, then lets one trial call through. Every key has a default.
- Type
object- Since
- 0.1.0
- Reload
- hot
upstreams.*.circuit_breaker.cooldown
How long the open breaker rests before the trial call; default 5s.
- Type
string- Default
5s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
upstreams.*.circuit_breaker.failure_ratio
Share of failing calls that opens the breaker, in (0, 1]; default 0.5.
- Type
number- Default
0.5- Bounds
- value ≥ 0, ≤ 1
- Since
- 0.1.0
- Reload
- hot
upstreams.*.circuit_breaker.min_requests
Minimum number of calls in the window before the ratio is judged; default 20.
- Type
integer- Default
20- Bounds
- value ≥ 1
- Since
- 0.1.0
- Reload
- hot
upstreams.*.circuit_breaker.window
Rolling window over which failures are counted; default 10s.
- Type
string- Default
10s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
upstreams.*.max_in_flight
Requests relayed to this upstream at once; past it, 503 at once (bulkhead). 0: no cap. For a broker, bounds the publications waiting for an acknowledgement, 1024 by default.
- Type
integer- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
upstreams.*.nats
NATS only: the gateway's identity and JetStream. One identity at most - credentials, nkey_seed or token, or sasl PLAIN; with none, an anonymous connection is admitted only with a client certificate or inside a declared mesh.
- Type
object- Since
- 1.6.0
- Reload
- hot
upstreams.*.nats.credentialssecret
NATS credentials file (JWT and nkey seed), by reference (${VAR} or file:/path).
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
upstreams.*.nats.domain
JetStream domain (a super-cluster, a leaf node), optional: one token, without dot, space, * nor >. Does nothing with jetstream: false, so refused.
- Type
string- Since
- 1.6.0
- Reload
- hot
upstreams.*.nats.jetstream
Publish and consume through JetStream (publications acknowledged by a stream); default true. false: NATS Core, read by server-sent events only, never published to.
- Type
boolean- Default
true- Since
- 1.6.0
- Reload
- hot
upstreams.*.nats.nkey_seedsecret
An nkey seed alone, by reference (${VAR} or file:/path).
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
upstreams.*.nats.tokensecret
NATS token, by reference; it is sent as it is, so TLS is required (tls or a tls:// broker).
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.6.0
- Reload
- hot
upstreams.*.pool
Connections kept to this upstream. Not for a broker or a webhook, which keep their own connections.
- Type
object- Since
- 0.2.0
- Reload
- hot
upstreams.*.pool.idle_timeout
How long an idle connection is kept before it is closed; default 90s.
- Type
string- Default
1m30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
upstreams.*.pool.max_conns
Connections open to the upstream at once; 0 (default): no cap. A cap turns a slowdown into queueing at the gateway instead of a connection storm.
- Type
integer- Bounds
- value ≥ 0
- Since
- 0.2.0
- Reload
- hot
upstreams.*.pool.max_idle
Idle connections kept for reuse; default 100. 0 or absent: the default - disabling reuse is not offered.
- Type
integer- Default
100- Since
- 0.2.0
- Reload
- hot
upstreams.*.protocol
The upstream's protocol: http (default, https:// included), grpc (HTTP/2, h2c in clear inside a mesh), mcp (a federated MCP server), a2a (an A2A agent, token_exchange required), kafka, amqp, mqtt, nats (brokers) or webhook (a delivery target).
- Type
string- Allowed values
httpgrpcmcpa2akafkaamqpmqttnatswebhook- Default
http- Since
- 0.1.0
- Reload
- hot
upstreams.*.protocol_version
Protocol version, AMQP and MQTT only: MQTT 5 (default) or 3.1.1; AMQP 0-9-1 (default) or 1.0. Kafka and NATS negotiate their version: the key is refused.
- Type
string- Allowed values
53.1.10-9-11.0- Since
- 1.5.0
- Reload
- hot
upstreams.*.retries.max
Retries of a delivery at most, from 0 to 20; default 8.
- Type
integer- Default
8- Bounds
- value ≥ 0, ≤ 20
- Since
- 1.5.0
- Reload
- hot
upstreams.*.retries.max_delay
Longest delay between two attempts; default 10m.
- Type
string- Default
10m- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.5.0
- Reload
- hot
upstreams.*.sasl
Brokers only: how the gateway authenticates to the broker - its own identity, never a caller's.
- Type
object- Since
- 1.5.0
- Reload
- hot
upstreams.*.sasl.mechanismrequired
SASL mechanism: Kafka PLAIN, SCRAM-SHA-256 or SCRAM-SHA-512; AMQP 0-9-1, MQTT and NATS PLAIN; AMQP 1.0 PLAIN, ANONYMOUS (with a client certificate or inside a mesh) or EXTERNAL (the client certificate as identity). PLAIN over TLS only.
- Type
string- Allowed values
PLAINSCRAM-SHA-256SCRAM-SHA-512ANONYMOUSEXTERNAL- Since
- 1.5.0
- Reload
- hot
upstreams.*.sasl.passwordsecret
Password, by reference (${VAR} or file:/path). Absent with ANONYMOUS and EXTERNAL.
- Type
string- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Secret
- a reference,
${VAR}orfile:/path, never a value in clear - Since
- 1.5.0
- Reload
- hot
upstreams.*.sasl.username
The gateway's user name at the broker. Absent with ANONYMOUS and EXTERNAL.
- Type
string- Since
- 1.5.0
- Reload
- hot
upstreams.*.secrets
Webhook only: signing secrets (Standard Webhooks), by reference - one, or two during a rotation.
- Type
list<string>- Bounds
- items ≤ 2
- Pattern
^(\$\{[A-Za-z_][A-Za-z0-9_]*\}|file:/\S+)$- Since
- 1.5.0
- Reload
- hot
upstreams.*.timeout
Total budget of an exchange with this upstream (3s), never a count of nanoseconds. Overrides server.timeouts.total, overridden in turn by x-flexway-timeout. For a broker: a publication's budget, acknowledgement included.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.2.0
- Reload
- hot
upstreams.*.tls
Client TLS toward the upstream outside a mesh: authority, client certificate, expected name. Only with an https:// URL (or a TLS broker); inside a mesh the sidecar does mTLS and the URL stays http://. No client certificate toward a webhook.
- Type
object- Since
- 0.3.0
- Reload
- hot
upstreams.*.tls.ca_file
Path of the authority (PEM) that verifies the upstream's certificate. Absent: the system authorities.
- Type
string- Since
- 0.3.0
- Reload
- hot
upstreams.*.tls.cert_file
Path of the client certificate (PEM) presented to the upstream; goes with key_file.
- Type
string- Since
- 0.3.0
- Reload
- hot
upstreams.*.tls.key_file
Path of the client certificate's private key (PEM); goes with cert_file.
- Type
string- Since
- 0.3.0
- Reload
- hot
upstreams.*.tls.server_name
Name expected in the upstream's certificate (SNI), when it differs from the URL's host.
- Type
string- Since
- 0.3.0
- Reload
- hot
upstreams.*.token_exchange
This upstream receives a token issued for it on the caller's behalf (RFC 8693), on every call, REST and MCP alike, never the caller's own and with no fallback. Requires a client at the caller's issuer. Refused for a broker or a webhook.
- Type
object- Since
- 0.1.0
- Reload
- hot
upstreams.*.token_exchange.audiencerequired
Audience the upstream expects a token to be issued for (orders-api). Required.
- Type
string- Since
- 0.1.0
- Reload
- hot
upstreams.*.token_exchange.scope
Scopes that narrow the exchanged token; empty: left to the provider.
- Type
list<string>- Since
- 0.1.0
- Reload
- hot
upstreams.*.url
The upstream's address: an absolute http(s) URL (http://orders.internal:8080), required except for a broker, reached through brokers. Webhook: an https:// URL named by a host, never an IP address, without credentials.
- Type
string- Since
- 0.1.0
- Reload
- hot
versionrequired
Version of the file's schema: 1, the only value accepted. Required.
- Type
integer- Allowed values
1- Since
- 0.1.0
- Reload
- hot
60 keys
Policy types
The config of a policy declared under policies.definitions follows its type: one entry per type, decoded strictly (an unknown key is refused).
policy.cache
Public response cache policy, declared under policies.definitions with type: cache and attached by a chain; looked up in the request phase. Applies to GET and HEAD only; its when condition is kept (for instance !has(auth.subject)). An authenticated cache is declared by the operation (x-flexway-cache), never by a policy.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.cache.scope
Cache scope: public only (default). subject is refused here: it is declared in the operation's x-flexway-cache.
- Type
string- Allowed values
public- Default
public- Since
- 1.2.0
- Reload
- hot
policy.cache.ttlrequired
How long a response is kept, a positive duration (60s); required.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.2.0
- Reload
- hot
policy.cors
CORS policy, declared under policies.definitions with type: cors, attached globally, per host, per route or per operation; request phase, no when condition. Closed by default: an origin not listed is refused.
- Type
object- Since
- 0.3.0
- Reload
- hot
policy.cors.allow_credentials
Allows browser requests with credentials (Access-Control-Allow-Credentials). Default false; refused with the * origin.
- Type
boolean- Since
- 0.3.0
- Reload
- hot
policy.cors.allow_headers
Request headers allowed beside the ones the operation declares. Empty: the operation's own whitelist only.
- Type
list<string>- Since
- 0.3.0
- Reload
- hot
policy.cors.allow_methods
Methods announced in the preflight answer. Empty: the methods the contract declares for the path.
- Type
list<string>- Since
- 0.3.0
- Reload
- hot
policy.cors.allow_originsrequired
Allowed origins (https://app.example.com), at least one; * admits any origin but never with allow_credentials.
- Type
list<string>- Bounds
- items ≥ 1
- Since
- 0.3.0
- Reload
- hot
policy.cors.expose_headers
Response headers the browser lets the script read (Access-Control-Expose-Headers).
- Type
list<string>- Since
- 0.3.0
- Reload
- hot
policy.cors.max_age
How long the browser keeps the preflight answer (Access-Control-Max-Age), a positive duration (10m); absent: the header is not sent.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.3.0
- Reload
- hot
policy.external-call
Call to a declared service whose answer may refuse the request (deny) or set headers (set_headers), nothing else; type: external-call under policies.definitions, request phase (default, before the upstream) or response. Timeout and on_failure are required, the operation's budget is consumed; a simulated request calls nothing.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.external-call.deny
Refuses the request when a condition holds on the external service's answer; when, status and code are all required. At least one of deny or set_headers is needed.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.external-call.deny.coderequired
Error code of the problem served, ^[a-z][a-z0-9_]{0,63}$; never one of the gateway's own codes (forbidden, rate_limited...).
- Type
string- Pattern
^[a-z][a-z0-9_]{0,63}$- Since
- 1.2.0
- Reload
- hot
policy.external-call.deny.statusrequired
Status of the refusal: a registered 4xx, other than 401, 405, 407 and 416.
- Type
integer- Bounds
- value ≥ 400, ≤ 499
- Since
- 1.2.0
- Reload
- hot
policy.external-call.deny.whenrequired
CEL condition on response.status and response.body - the external service's answer, never the upstream's.
- Type
string- Since
- 1.2.0
- Reload
- hot
policy.external-call.on_failurerequired
What happens without a usable answer (timeout, error, open breaker): fail-open goes on as if the policy did not apply, fail-closed refuses. Required, no default.
- Type
string- Allowed values
fail-openfail-closed- Since
- 1.2.0
- Reload
- hot
policy.external-call.pathrequired
Path called on the upstream, a literal starting with /, without ?, #, {, } or space.
- Type
string- Pattern
^/[^?#{} ]*$- Since
- 1.2.0
- Reload
- hot
policy.external-call.send
What the call sends to the external service; nothing by default.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.external-call.send.body
Sends the request's body. Refused in the response phase, where it is already relayed.
- Type
boolean- Since
- 1.2.0
- Reload
- hot
policy.external-call.send.headers
Headers of the request prepared for the upstream to send along (declared headers, the tenant written by the gateway); 32 at most. Never an undeclared header of the caller.
- Type
list<string>- Bounds
- items ≤ 32
- Since
- 1.2.0
- Reload
- hot
policy.external-call.set_headers
Headers set from the external answer: name -> CEL expression on response; 32 at most, values of 4,096 bytes at most (beyond, the call failed). Protected headers are refused.
- Type
map<string>- Since
- 1.2.0
- Reload
- hot
policy.external-call.timeoutrequired
Timeout of the call, a positive duration (200ms); required. The call also consumes the operation's budget.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.2.0
- Reload
- hot
policy.external-call.upstreamrequired
Upstream called, declared in upstreams, over HTTP and without token_exchange; required.
- Type
string- Since
- 1.2.0
- Reload
- hot
policy.header-inject
Sets or renames headers; type: header-inject under policies.definitions, request phase (default), response or error, optional when condition. Protected headers (identity, forwarding, tracing, hop-by-hop, flexway-*, the tenant header) are refused.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.header-inject.on_missing
What a template does when its value is missing: skip (header not set), empty (set empty) or fail (request refused). Required as soon as a value is an expression; skip otherwise.
- Type
string- Allowed values
skipemptyfail- Since
- 0.1.0
- Reload
- hot
policy.header-inject.rename
Headers renamed: old name -> new name, values kept.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
policy.header-inject.set
Headers set: name -> value, literal or a {{ CEL expression }} template ({{ auth.claims.plan }}); an existing value is replaced. At least one of set or rename.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
policy.header-remove
Removes headers; type: header-remove under policies.definitions, request phase (default), response or error. Protected headers are refused.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.header-remove.namesrequired
Names of the headers removed, at least one.
- Type
list<string>- Bounds
- items ≥ 1
- Since
- 0.1.0
- Reload
- hot
policy.map-status
Turns an upstream response's status into a semantic one; type: map-status under policies.definitions, response phase. Its configuration is a list of 1 to 64 rules { from, to, when, code }, the first that applies wins; a rule after an unconditional rule with the same from is refused.
- Type
list<object>- Bounds
- items ≥ 1, ≤ 64
- Since
- 1.2.0
- Reload
- hot
policy.map-status.*.code
Error code of the problem served, only when to is 400 or more; ^[a-z][a-z0-9_]{0,63}$, never one of the gateway's own codes.
- Type
string- Pattern
^[a-z][a-z0-9_]{0,63}$- Since
- 1.2.0
- Reload
- hot
policy.map-status.*.fromrequired
Upstream status matched, from 200 to 599; required.
- Type
integer- Bounds
- value ≥ 200, ≤ 599
- Since
- 1.2.0
- Reload
- hot
policy.map-status.*.torequired
Status served, required: 200 or more, with an RFC 9110 reason, different from from, never a 3xx nor 204, 205, 206, 304, 401, 405, 407, 416 or 426.
- Type
integer- Bounds
- value ≥ 200, ≤ 599
- Since
- 1.2.0
- Reload
- hot
policy.map-status.*.when
Optional CEL condition, which may read body, the response's JSON body.
- Type
string- Since
- 1.2.0
- Reload
- hot
policy.query-inject
Sets query parameters; type: query-inject under policies.definitions, request phase.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.query-inject.on_missing
What a template does when its value is missing: skip, empty or fail. Required as soon as a value is an expression; skip otherwise.
- Type
string- Allowed values
skipemptyfail- Since
- 0.1.0
- Reload
- hot
policy.query-inject.setrequired
Parameters set: name -> value, literal or a {{ CEL expression }} template; at least one.
- Type
map<string>- Since
- 0.1.0
- Reload
- hot
policy.query-remove
Removes query parameters; type: query-remove under policies.definitions, request phase.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.query-remove.namesrequired
Names of the parameters removed, at least one.
- Type
list<string>- Bounds
- items ≥ 1
- Since
- 0.1.0
- Reload
- hot
policy.quota
A tenant's request quota over calendar windows, UTC (day, month); type: quota under policies.definitions, request phase, no condition. Requires server.counters: counted in memory, a monthly quota would start again at every deployment. Beyond it: 429 quota_exceeded.
- Type
object- Since
- 1.0.0
- Reload
- hot
policy.quota.key
What is counted: tenant only (default).
- Type
string- Allowed values
tenant- Default
tenant- Since
- 1.0.0
- Reload
- hot
policy.quota.limitsrequired
Limits by window: day and/or month, each an integer of at least 1; at least one window.
- Type
map<integer>- Since
- 1.0.0
- Reload
- hot
policy.rate-limit
Token buckets per caller; type: rate-limit under policies.definitions, request phase, no condition. An operation takes the class read (GET, HEAD, OPTIONS) or write, or the one of x-flexway-rate-class; beyond it: 429 rate_limited.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.rate-limit.classesrequired
Rate classes by name (read, write, or your own), each a bucket; at least one.
- Type
map<object>- Since
- 0.1.0
- Reload
- hot
policy.rate-limit.classes.*.burstrequired
Bucket size: requests admitted at once; an integer of at least 1, required.
- Type
integer- Bounds
- value ≥ 1
- Since
- 0.1.0
- Reload
- hot
policy.rate-limit.classes.*.rpsrequired
Bucket refill, in requests per second; a number greater than 0, required.
- Type
number- Bounds
- value > 0
- Since
- 0.1.0
- Reload
- hot
policy.rate-limit.classes.*.scope
Overrides the policy's scope for this class: class or operation.
- Type
string- Allowed values
classoperation- Since
- 1.0.0
- Reload
- hot
policy.rate-limit.header
With key: header, the header whose value keys an anonymous caller.
- Type
string- Since
- 1.0.0
- Reload
- hot
policy.rate-limit.key
What a bucket counts: caller (default) - the authenticated subject, else the client address - or header - for an anonymous caller, the value of header, believed only from a peer whose identity is in trusted. An authenticated subject stays the key either way.
- Type
string- Allowed values
callerheader- Default
caller- Since
- 0.1.0
- Reload
- hot
policy.rate-limit.scope
What one bucket spans: class (default) - one bucket per caller and class, shared by the class's operations - or operation - one bucket per caller and operation, the class giving its size.
- Type
string- Allowed values
classoperation- Default
class- Since
- 1.0.0
- Reload
- hot
policy.rate-limit.trusted
With key: header, the verified peer identities (through server.peer_identity_header) whose key header is believed; required with key: header.
- Type
list<string>- Since
- 1.0.0
- Reload
- hot
policy.redact
Masks or removes fields of the response's JSON body; type: redact under policies.definitions, response phase. Exactly one of with or remove: true.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.redact.fieldsrequired
Field paths, starting with body. (body.card.number), segments [A-Za-z_][A-Za-z0-9_]*; 1 to 256 paths, 32 segments at most, no duplicate.
- Type
list<string>- Bounds
- items ≥ 1, ≤ 256
- Pattern
^body\.- Since
- 1.2.0
- Reload
- hot
policy.redact.remove
true removes the fields instead of masking them; never with with.
- Type
boolean- Since
- 1.2.0
- Reload
- hot
policy.redact.with
Value a masked field is replaced by: a string, a number, a boolean or null; never with remove: true.
- Type
string | number | boolean | null- Since
- 1.2.0
- Reload
- hot
policy.rewrite-path
Points the request at another path on the upstream; type: rewrite-path under policies.definitions, request phase.
- Type
object- Since
- 0.1.0
- Reload
- hot
policy.rewrite-path.torequired
Upstream path, starting with /; {param} takes the value of a route parameter, escaped, never the raw text of the path received.
- Type
string- Pattern
^/- Since
- 0.1.0
- Reload
- hot
policy.transform-body
Closed projection of the response's JSON body: only the fields listed are served; type: transform-body under policies.definitions, response phase. Body bounded by server.body.max_bytes.
- Type
object- Since
- 1.2.0
- Reload
- hot
policy.transform-body.on_missingrequired
Projected field absent from the response: fail (response refused) or omit (field left out). Required.
- Type
string- Allowed values
failomit- Since
- 1.2.0
- Reload
- hot
policy.transform-body.projectrequired
Dotted paths of the fields kept (id, customer.name), segments [A-Za-z_][A-Za-z0-9_]*; 1 to 256 paths, 32 segments at most.
- Type
list<string>- Bounds
- items ≥ 1, ≤ 256
- Since
- 1.2.0
- Reload
- hot
67 keys
Contract extensions
The x-flexway-* extensions a contract carries (OpenAPI, AsyncAPI, A2A agent card) and the gRPC option flexway.v1.operation. A closed list: an x-flexway-* extension that is unknown, not served yet or written where it is not read is refused at load.
x-flexway-a2a
Governance block of an A2A agent, at the top level of its declared card (contracts.a2a), required; removed from the published card. Unknown keys are refused.
- Type
object- Read in
- A2A agent card
- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.delegation
Bounds of the agent chain for this agent { max_depth, max_age }: requires agents.delegation and may only tighten it - a wider bound is refused.
- Type
object- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.delegation.max_age
Maximum age since the person authenticated, a positive duration; never beyond agents.delegation.max_age.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.delegation.max_depth
Maximum number of agents in the chain, an integer of 0 or more; never beyond agents.delegation.max_depth.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.max_streams
Streams open at most per replica for this agent; required and greater than 0 when the card announces capabilities.streaming.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.max_task_duration
Maximum duration of a task followed as a stream, a positive duration (10m); required when the card announces capabilities.streaming.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.methods
Rate class per A2A method (SendMessage, GetTask, CancelTask...), ^[a-z][a-z0-9_-]{0,31}$. Default: write for sends, CancelTask and creating or deleting a push notification configuration, free for the rest.
- Type
map<string>- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.signer
Signer of the published card: not accepted yet, any value is refused.
- Type
string- Since
- 1.10.0
- Reload
- hot
x-flexway-a2a.upstreamrequired
Upstream that serves the agent, declared in upstreams with protocol: a2a (hence token_exchange); required.
- Type
string- Since
- 1.2.0
- Reload
- hot
x-flexway-a2a.verifyrequired
Verification of the upstream's card: none only, required.
- Type
string- Allowed values
none- Since
- 1.2.0
- Reload
- hot
x-flexway-ai
Name of the ai option of flexway.v1.operation on a gRPC method: the method is a metered model. Refused in an OpenAPI or AsyncAPI contract.
- Type
object- Read in
- gRPC method
- Since
- 1.5.0
- Reload
- hot
x-flexway-ai.capability
Capability of the series: model (default), vision, embeddings or chat.
- Type
string- Allowed values
modelvisionembeddingschat- Default
model- Since
- 1.5.0
- Reload
- hot
x-flexway-ai.price_per_1k
Price of a thousand units, in euros; zero or more.
- Type
number- Bounds
- value ≥ 0
- Since
- 1.5.0
- Reload
- hot
x-flexway-ai.unit
Unit counted: call (default) or byte (bytes of the request and of the answer).
- Type
string- Allowed values
callbyte- Default
call- Since
- 1.5.0
- Reload
- hot
x-flexway-bind
On an AsyncAPI channel parameter: binds the parameter to a fact of the verified identity, never read from the request - tenant, subject, claim:<name> (a name of 1 to 64 characters [A-Za-z0-9_.-]) or, on an x-flexway-device operation, cert:<field> of the device certificate - cn, serial, fingerprint, or with its index ou[i], o[i], san.dns[i], san.uri[i], san.ip[i], san.email[i]. Required on every parameter of a channel in use, which must appear in the address.
- Type
string- Pattern
^(tenant|subject|claim:[A-Za-z0-9_.-]{1,64}|cert:(cn|serial|fingerprint|(ou|o|san\.dns|san\.uri|san\.ip|san\.email)\[[0-9]{1,2}\]))$- Read in
- AsyncAPI parameter
- Since
- 1.5.0
- Reload
- hot
x-flexway-cache
On an OpenAPI GET or HEAD operation: the operation's own response cache, { ttl, scope }. Refused on a stream, a WebSocket, a gRPC method, an A2A operation, a broker door, and together with a cache policy named by x-flexway-policies.
- Type
object- Read in
- OpenAPI operation
- Since
- 1.2.0
- Reload
- hot
x-flexway-cache.scope
public (default): shared, refused when the operation requires an identity; subject: keyed by tenant and subject, the only way an authenticated response is cached, refused on an operation without security.
- Type
string- Allowed values
publicsubject- Default
public- Since
- 1.2.0
- Reload
- hot
x-flexway-cache.ttlrequired
How long a response is kept, a positive duration (30s); required.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.2.0
- Reload
- hot
x-flexway-delegation
On an OpenAPI operation: tightens the agent chain bounds for it, { max_depth, max_age }; never wider than agents.delegation, which applies otherwise.
- Type
object- Read in
- OpenAPI operation
- Since
- 0.1.0
- Reload
- hot
x-flexway-delegation.max_age
Maximum age since the person authenticated, a positive duration; absent: the configuration's bound.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 0.1.0
- Reload
- hot
x-flexway-delegation.max_depth
Maximum number of agents in the chain, an integer of 0 or more (0 refuses any delegated token); absent: the configuration's bound.
- Type
integer- Bounds
- value ≥ 0
- Since
- 0.1.0
- Reload
- hot
x-flexway-deliver
On an AsyncAPI receive operation: webhook deliveries of its messages, with no caller - a list of targets { upstream, tenant, dead_letter }. Refused on MQTT 3.1.1 and NATS Core.
- Type
list<object>- Read in
- AsyncAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-deliver.*.dead_letterrequired
Dead-letter channel a message goes to when the target did not accept it after the retries; required, without { } or wildcard.
- Type
string- Pattern
^[^{}*>+#\s][^{}*>+#]*$- Since
- 1.5.0
- Reload
- hot
x-flexway-deliver.*.tenant
Tenant whose messages are delivered, 1 to 128 characters [A-Za-z0-9_-]; required unless the operation is public.
- Type
string- Pattern
^[A-Za-z0-9_-]{1,128}$- Since
- 1.5.0
- Reload
- hot
x-flexway-deliver.*.upstreamrequired
Target, an upstream declared with protocol: webhook; required.
- Type
string- Since
- 1.5.0
- Reload
- hot
x-flexway-device
On an AsyncAPI operation: serves it to devices on the listeners.mqtt listener - send: a device publishes, receive: it subscribes. true, or an object of the keys below. Requires an MQTT upstream (one for every device operation), a security and a channel whose parameters are bound, the tenant among them; never public.
- Type
boolean | object- Read in
- AsyncAPI operation
- Since
- 1.7.0
- Reload
- hot
x-flexway-device.bytes_per_second
On a send operation: overrides listeners.mqtt.device.bytes_per_second for it.
- Type
integer- Bounds
- value ≥ 1
- Since
- 1.7.0
- Reload
- hot
x-flexway-device.messages_per_second
On a send operation: overrides listeners.mqtt.device.messages_per_second for it.
- Type
number- Bounds
- value > 0
- Since
- 1.7.0
- Reload
- hot
x-flexway-device.qos_max
Highest QoS on the channel; past it a PUBLISH is refused 0x9B and a subscription granted at it. From 0 to 2, default 2.
- Type
integer- Default
2- Bounds
- value ≥ 0, ≤ 2
- Since
- 1.7.0
- Reload
- hot
x-flexway-encrypt
On an AsyncAPI message: fields written encrypted by the gateway on the Kafka listener - a non-empty list of dotted paths (card.number), without [, ], * or space, no duplicate nor path containing another. JSON message (a declared string field), Avro or Protobuf; requires kms.
- Type
list<string>- Bounds
- items ≥ 1, ≤ 255
- Pattern
^[^.\s\[\]*]+(\.[^.\s\[\]*]+)*$- Read in
- AsyncAPI message
- Since
- 1.6.0
- Reload
- hot
x-flexway-kafka-proxy
On an AsyncAPI operation: serves it to native Kafka clients on the listeners.kafka listener - send: a client produces, receive: it reads. Requires a Kafka upstream, a security and a channel <prefix>{tenant}.<name> bound to the tenant; never public.
- Type
object- Read in
- AsyncAPI operation
- Since
- 1.6.0
- Reload
- hot
x-flexway-kafka-proxy.admin_scope
Scope that opens the bounded administration of the virtual cluster; absent: administration is refused.
- Type
string- Bounds
- length ≥ 1
- Since
- 1.6.0
- Reload
- hot
x-flexway-kafka-proxy.clusterrequired
Name of the virtual cluster, a DNS label of 1 to 63 characters [a-z0-9-]; required.
- Type
string- Pattern
^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$- Since
- 1.6.0
- Reload
- hot
x-flexway-kafka-proxy.decrypt_scope
On a receive operation only: scope that receives the message's x-flexway-encrypt fields in clear; without it, they stay encrypted.
- Type
string- Bounds
- length ≥ 1
- Since
- 1.6.0
- Reload
- hot
x-flexway-kafka-proxy.transactions
On a send operation only: allows transactional producers. Default false.
- Type
boolean- Since
- 1.6.0
- Reload
- hot
x-flexway-key
On an AsyncAPI operation: JSON pointer (starting with /) to the ordering key in the message, the Kafka record key; no effect on MQTT and AMQP.
- Type
string- Pattern
^/- Read in
- AsyncAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-owner
In an OpenAPI document's info or on an operation, the operation wins: team that answers for the operation, { team, contact }. Shown in the catalogue, never read on the request path.
- Type
object- Read in
- OpenAPI info block · OpenAPI operation
- Since
- 1.2.0
- Reload
- hot
x-flexway-owner.contact
How to reach the team - a channel, a list, a page; 128 characters at most, never a person.
- Type
string- Bounds
- length ≤ 128
- Since
- 1.2.0
- Reload
- hot
x-flexway-owner.teamrequired
Team name, required, not blank, 128 characters at most.
- Type
string- Bounds
- length ≥ 1, ≤ 128
- Since
- 1.2.0
- Reload
- hot
x-flexway-policies
On an OpenAPI operation: its own level of the chain global -> host -> routes -> operation, a list of names from policies.definitions; !name removes a policy of a broader level.
- Type
string | list<string>- Read in
- OpenAPI operation
- Since
- 0.1.0
- Reload
- hot
x-flexway-priority
On an OpenAPI operation: shedding priority under saturation - critical (never shed), normal (default) or sheddable (shed first).
- Type
string- Allowed values
criticalnormalsheddable- Default
normal- Read in
- OpenAPI operation
- Since
- 1.0.0
- Reload
- hot
x-flexway-public
On an AsyncAPI receive operation: true lets anyone consume it, an anonymous caller included - written, never implied. Refused when the channel binds a parameter or carries the tenant attribute, and with x-flexway-kafka-proxy.
- Type
boolean- Read in
- AsyncAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-publish
On an OpenAPI POST operation: HTTP door of an AsyncAPI send operation, { operation, idempotency }. The body is published as CloudEvents and the 202 answer leaves after the broker's acknowledgement; never with x-flexway-subscribe, a cache or a body policy, nor for an anonymous caller.
- Type
object- Read in
- OpenAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-publish.idempotency
required refuses a publication without an Idempotency-Key header; absent: optional.
- Type
string- Allowed values
required- Since
- 1.5.0
- Reload
- hot
x-flexway-publish.operationrequired
Id of the send operation of contracts.asyncapi, with exactly one message, whose schema is the body's; required.
- Type
string- Since
- 1.5.0
- Reload
- hot
x-flexway-rate-class
On an OpenAPI operation: rate-limit class, defined by the chain's rate-limit policy on every host; absent: read or write by method.
- Type
string- Read in
- OpenAPI operation
- Since
- 0.1.0
- Reload
- hot
x-flexway-scopes
On an OpenAPI operation: scopes added to every token alternative of security (a string or a list); removes the anonymous alternative, leaves API keys and certificates unchanged. It can only add.
- Type
string | list<string>- Read in
- OpenAPI operation
- Since
- 0.3.0
- Reload
- hot
x-flexway-source
On an AsyncAPI operation: the CloudEvents source attribute of what it publishes; absent: //<request host>/<operation id>.
- Type
string- Read in
- AsyncAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-sparkplug
On an AsyncAPI operation served to devices (x-flexway-device): its role in the Sparkplug B 3.0 namespace - edge_node (channel spBv1.0/{group}/+/{node}/#: send publishes births, deaths and data, an NDEATH will only; receive gets its commands), host (channel spBv1.0/{group}/#: send publishes NCMD and DCMD, every token alternative naming scopes; receive reads the group), state (channel spBv1.0/STATE/{host}, the host bound to the tenant). The group is always bound to the tenant. Without a declared message, the payload is read under the embedded sparkplug_b.proto descriptor (validated with x-flexway-validation: full).
- Type
string- Allowed values
edge_nodehoststate- Read in
- AsyncAPI operation
- Since
- 1.7.0
- Reload
- hot
x-flexway-subscribe
On an OpenAPI GET operation: a stream of the caller's tenant's messages for an AsyncAPI receive operation, as server-sent events or a WebSocket. Anonymous only when the AsyncAPI operation is public; never with x-flexway-tool, a cache or a body policy.
- Type
object- Read in
- OpenAPI operation
- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.ack_timeout
Acknowledgement timeout of a WebSocket message, a positive duration; default 30s.
- Type
string- Default
30s- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.buffer
Messages buffered per subscriber, from 1 to 4,096; default 64.
- Type
integer- Default
64- Bounds
- value ≥ 1, ≤ 4096
- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.frames
Form of WebSocket frames: json (default) or binary, which requires websocket in transport and a binary message.
- Type
string- Allowed values
jsonbinary- Default
json- Since
- 1.6.0
- Reload
- hot
x-flexway-subscribe.history
Messages kept in memory per channel for an SSE resume (Last-Event-ID), from 0 to 1,024; default 64. 0: no history, resume refused.
- Type
integer- Default
64- Bounds
- value ≥ 0, ≤ 1024
- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.max_anonymous_streams
Anonymous streams open at most, all callers together, per replica; 0 (default): no cap of its own.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.max_streams
Streams open at most per caller and replica; 0 (default): no cap of its own.
- Type
integer- Bounds
- value ≥ 0
- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.operationrequired
Id of the receive operation of contracts.asyncapi; required.
- Type
string- Since
- 1.5.0
- Reload
- hot
x-flexway-subscribe.transport
Transports offered, a list of sse and websocket; default: both.
- Type
list<string>- Allowed values
ssewebsocket- Default
["sse","websocket"]- Since
- 1.5.0
- Reload
- hot
x-flexway-sunset
In an OpenAPI document's info or on an operation, the operation wins: withdrawal date, YYYY-MM-DD. The operation must be deprecated: true; set in info, every operation without its own value must be.
- Type
string- Pattern
^[0-9]{4}-[0-9]{2}-[0-9]{2}$- Read in
- OpenAPI info block · OpenAPI operation
- Since
- 1.2.0
- Reload
- hot
x-flexway-timeout
On an OpenAPI operation: total budget of the operation, retries included, a positive duration (2s, 500ms); overrides upstreams.*.timeout, then server.timeouts.total.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Read in
- OpenAPI operation
- Since
- 0.2.0
- Reload
- hot
x-flexway-tool
On an OpenAPI operation: offers it as a tool on the MCP surface, under the same decision as REST. true (a tool named after the operationId), false, or an object { name, description, unattended }. Refused with x-flexway-subscribe and on an SSE stream.
- Type
boolean | object- Read in
- OpenAPI operation
- Since
- 0.1.0
- Reload
- hot
x-flexway-tool.description
Tool description; default: the operation's summary, then its description.
- Type
string- Since
- 0.1.0
- Reload
- hot
x-flexway-tool.name
Tool name, ^[A-Za-z0-9_.-]{1,128}$, unique per host; default: the operationId.
- Type
string- Pattern
^[A-Za-z0-9_.-]{1,128}$- Since
- 0.1.0
- Reload
- hot
x-flexway-tool.unattended
false keeps the tool for agents a person supervises; default true.
- Type
boolean- Default
true- Since
- 1.0.0
- Reload
- hot
x-flexway-upstream
On an OpenAPI operation: upstream it is relayed to, declared in upstreams; absent: the host's default_upstream. On an AsyncAPI operation: required, the broker upstream (kafka, amqp, mqtt, nats) it publishes to or consumes from.
- Type
string- Read in
- AsyncAPI operation · OpenAPI operation
- Since
- 0.1.0
- Reload
- hot
x-flexway-validation
Validation mode of the operation. OpenAPI: full, params (the body is relayed unread) or off, overrides hosts.*.validation. AsyncAPI: full or off only; default full for a JSON message (where off is refused), off for a binary message.
- Type
string- Allowed values
fullparamsoff- Read in
- AsyncAPI operation · OpenAPI operation
- Since
- 1.0.0
- Reload
- hot
21 keys
gRPC option
In the .proto, option (flexway.v1.operation) = { ... };: for a gRPC method, the counterpart of an OpenAPI operation's extensions.
flexway.v1.operation
gRPC method option (option (flexway.v1.operation) = { ... }; in the .proto): what the gateway needs to know about a method, the counterpart of an OpenAPI operation's x-flexway-* extensions. Read from the descriptor set with its imports; every field is optional, the host's default applies otherwise.
- Type
object- Read in
- gRPC method
- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.ai
Makes the method a specialised model metered by the inference plane (the counterpart of x-flexway-ai): counted into the tenant's euro budget, per call or per byte, without reading the body. Requires an ai section and a kind: grpc backend of ai.backends naming the method's upstream.
- Type
object- Since
- 1.5.0
- Reload
- hot
flexway.v1.operation.ai.capability
Capability the series are labelled with: model (default), vision, embeddings or chat.
- Type
string- Allowed values
modelvisionembeddingschat- Default
model- Since
- 1.5.0
- Reload
- hot
flexway.v1.operation.ai.price_per_1k
Price of a thousand units, in euros; zero or more (0 is a price).
- Type
number- Bounds
- value ≥ 0
- Since
- 1.5.0
- Reload
- hot
flexway.v1.operation.ai.unit
Unit counted: call (default), one unit per call; byte, one per byte of the request and of the answer.
- Type
string- Allowed values
callbyte- Default
call- Since
- 1.5.0
- Reload
- hot
flexway.v1.operation.metadata
Request metadata allowed through to the upstream, beside gRPC's own: closed by default, metadata not listed does not pass.
- Type
list<string>- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.owner
Team that answers for the method (the counterpart of x-flexway-owner): shown in the console's catalogue, never read on the request path.
- Type
object- Since
- 1.2.0
- Reload
- hot
flexway.v1.operation.owner.contact
How to reach the team - a channel, a list, a page; 128 characters at most. Never a person: every reader of the catalogue sees it.
- Type
string- Bounds
- length ≤ 128
- Since
- 1.2.0
- Reload
- hot
flexway.v1.operation.owner.teamrequired
Team name, required as soon as owner is written; not blank, 128 characters at most.
- Type
string- Bounds
- length ≥ 1, ≤ 128
- Since
- 1.2.0
- Reload
- hot
flexway.v1.operation.policies
The method's own level of the policy chain (the counterpart of x-flexway-policies): names from policies.definitions; !name removes a policy a broader level brought.
- Type
list<string>- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.priority
Shedding priority: critical (never shed), normal (default) or sheddable (shed first).
- Type
string- Allowed values
criticalnormalsheddable- Default
normal- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.rate_class
Rate-limit class of the method (the counterpart of x-flexway-rate-class), defined by the chain's rate-limit policy. Empty: read for a method without side effects or bound to GET, write otherwise.
- Type
string- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security
Access alternatives, any one of which suffices - like an OpenAPI security list. Empty: no identity required.
- Type
list<object>- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security.*.anonymous
The empty alternative: no identity required. Takes precedence over the alternative's other fields.
- Type
boolean- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security.*.api_key
An API key bound to the method (Authorization: ApiKey ...) satisfies this alternative; scopes and roles are ignored there.
- Type
boolean- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security.*.mutual_tls
A client certificate bound to the method satisfies this alternative; scopes and roles are ignored there.
- Type
boolean- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security.*.roles
Roles a token must all carry, read from its issuer's roles_claim.
- Type
list<string>- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.security.*.scopes
Scopes a token must all carry.
- Type
list<string>- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.sunset
Date the method is withdrawn, YYYY-MM-DD (the counterpart of x-flexway-sunset). Only on a method marked option deprecated = true;: refused at load otherwise.
- Type
string- Pattern
^[0-9]{4}-[0-9]{2}-[0-9]{2}$- Since
- 1.2.0
- Reload
- hot
flexway.v1.operation.timeout
Total budget of one call, a positive duration (3s); empty: the upstream's.
- Type
string- Pattern
^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$- Since
- 1.1.0
- Reload
- hot
flexway.v1.operation.upstream
Upstream that serves the method, declared in upstreams; empty: the host's default upstream.
- Type
string- Since
- 1.1.0
- Reload
- hot