<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Configuration reference on Gate One</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/</link><description>Recent content in Configuration reference on Gate One</description><generator>Hugo</generator><language>en</language><atom:link href="https://clad-one.github.io/gate-one-doc/latest/docs/config/index.xml" rel="self" type="application/rss+xml"/><item><title>Gate One configuration</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/gate-one/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/gate-one/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/api-routes.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The &lt;code&gt;api-routes.json&lt;/code&gt; file consumed by the &lt;code&gt;gate-one&lt;/code&gt; binary. Relative paths (certificates, keys, plugin artefacts, WAL directories) are resolved from the configuration file.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect1"&gt;&#10;&lt;h2 id="config-root"&gt;Fields&lt;/h2&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders"&gt;&lt;/a&gt; &lt;code&gt;securityHeaders&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-securityHeaders"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Platform-wide response hardening, emitted by the gateway on EVERY response it serves (proxied or generated: health, stats, 401/403, MCP metadata, PWA assets, CSP collector). Declaring the block applies the secure defaults; each field can be tightened or disabled. Referrer-Policy is only set when the response does not already carry one (a proxified app’s stricter policy wins). Absent = nothing (an install whose edge proxy already sets them can opt out).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license"&gt;&lt;/a&gt; &lt;code&gt;license&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-license"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional offline signed licence (Ed25519), one token per period. Absent, invalid or expired = evaluation/personal mode: the gateway keeps serving; the user badge shows a notice. The private signing key NEVER ships (only publicKey is embedded).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider"&gt;&lt;/a&gt; &lt;code&gt;authProvider&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Authentication provider. &lt;code&gt;dev&lt;/code&gt; is the embedded loopback-only IdP used for onboarding/tests; &lt;code&gt;http-bridge&lt;/code&gt; is any external service implementing the Gate One HTTP bridge contract (auth-bridge is the reference implementation; a non-conforming service needs an adapter); &lt;code&gt;oidc&lt;/code&gt; is the native Relying Party (discovery, code+PKCE, JWKS, session, logout, MCP resource server); &lt;code&gt;jwt&lt;/code&gt; is a stateless bearer verifier. Absent = legacy oidc + auth-bridge translation, so existing configs are unchanged. The legacy type &lt;code&gt;http&lt;/code&gt; is accepted as a deprecated alias of &lt;code&gt;http-bridge&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProviders"&gt;&lt;/a&gt; &lt;code&gt;authProviders&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of object&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Named authentication providers for per-route binding. Mutually exclusive with the legacy singular authProvider. Each item uses the same fields as authProvider plus id/cookieName; a route selects one with auth.provider.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-defaultAuthProvider"&gt;&lt;/a&gt; &lt;code&gt;defaultAuthProvider&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Provider id used by routes that do not set auth.provider. Required when more than one authProviders entry is declared.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-defaultAppUrl"&gt;&lt;/a&gt; &lt;code&gt;defaultAppUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Global fallback for a bare visit to a login host root (302), preserving the query string. A provider’s own defaultAppUrl wins for its login host. Email verification/account links must carry a return target; use defaultAppUrl only as an operational fallback. Point it at a neutral page (e.g. your landing), not at one application.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-oidc"&gt;&lt;/a&gt; &lt;code&gt;oidc&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-oidc"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;LEGACY platform IdP block. When authProvider is absent, it is translated into an http provider (auth-bridge) at load; existing configs keep working. New configurations should use authProvider.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker"&gt;&lt;/a&gt; &lt;code&gt;tokenBroker&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-tokenBroker"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Internal per-user credential broker. Required when a route declares upstream.tokenBroker; a configured block also keeps the Services page (/connections: pause/resume/erase) available when no route delegates. The shared secret is read from the named environment variable at load (never from this file) and is never logged.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpDefaults"&gt;&lt;/a&gt; &lt;code&gt;mcpDefaults&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-mcpDefaults"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional defaults shared by every MCP access unit.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets"&gt;&lt;/a&gt; &lt;code&gt;mcpSets&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-mcpSets"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Named groups of MCP services exposed with their own access rights (resource/scope/identity) and per-member tool filters. A member endpoint is set.host + set.endpoint + member.path.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publisherFeed"&gt;&lt;/a&gt; &lt;code&gt;publisherFeed&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-publisherFeed"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional signed publisher feed: compatible Gate One versions, external components and plugins, with their revocation status. Loaded and verified at startup; the operator’s trust store stays authoritative. Absent = no feed is consulted.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile"&gt;&lt;/a&gt; &lt;code&gt;turnstile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-turnstile"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Platform-wide Cloudflare Turnstile bot check for form pages. Presence enables it (explicit enabled=false disables it in templated configs). The widget is injected into matching HTML pages and every matching request is verified against the Siteverify API BEFORE the backend: a missing/invalid token is answered 403 (readable page for a navigation, JSON otherwise), a Siteverify outage 503 (fail closed). The block is global on purpose: one place to change, no per-host duplication. LIMITATION: it protects only traffic that passes through this Gate One instance; a second ingress, an internal caller or a direct port reaching the application bypasses it. Network isolation (only Gate One can reach the application) remains required. The token is never logged nor written to usage events.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage"&gt;&lt;/a&gt; &lt;code&gt;usage&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-usage"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Out-of-process usage-event bus (WAL + extension plugins). Presence enables it. Events are produced only for the subscribed types; a full durable share is answered with a targeted 503 (health/readyz/auth-probe exempt).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes"&gt;&lt;/a&gt; &lt;code&gt;routes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-routes"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Routes served by this gateway. Order is not significant: the most specific host/path match wins.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups"&gt;&lt;/a&gt; &lt;code&gt;ssoGroups&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-ssoGroups"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Cross-domain SSO groups. Shared OIDC/client/session settings are declared once per group; providers[] declares only what varies per application domain. Expanded into authProviders at load. Auth-registry is exhaustive: a shared field placed in a provider entry is rejected by the strict decoder.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-securityHeaders"&gt;securityHeaders&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Platform-wide response hardening, emitted by the gateway on EVERY response it serves (proxied or generated: health, stats, 401/403, MCP metadata, PWA assets, CSP collector). Declaring the block applies the secure defaults; each field can be tightened or disabled. Referrer-Policy is only set when the response does not already carry one (a proxified app’s stricter policy wins). Absent = nothing (an install whose edge proxy already sets them can opt out).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders-hstsMaxAge"&gt;&lt;/a&gt; &lt;code&gt;hstsMaxAge&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Strict-Transport-Security max-age, in seconds. Absent = 15552000 (180 days); 0 = header omitted (e.g. a host that must stay reachable in plain HTTP). Keep includeSubDomains/preload off until every subdomain is HTTPS-only: with preload the choice becomes permanent in browsers. Minimum: 0. Maximum: 63072000.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders-hstsIncludeSubDomains"&gt;&lt;/a&gt; &lt;code&gt;hstsIncludeSubDomains&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Append includeSubDomains. Default false.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders-hstsPreload"&gt;&lt;/a&gt; &lt;code&gt;hstsPreload&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Append preload. Requires hstsIncludeSubDomains (refused at load otherwise). Default false.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders-nosniff"&gt;&lt;/a&gt; &lt;code&gt;nosniff&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;X-Content-Type-Options: nosniff. Default true.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-securityHeaders-referrerPolicy"&gt;&lt;/a&gt; &lt;code&gt;referrerPolicy&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;`, `no-referrer&lt;/code&gt;, &lt;code&gt;no-referrer-when-downgrade&lt;/code&gt;, &lt;code&gt;origin&lt;/code&gt;, &lt;code&gt;origin-when-cross-origin&lt;/code&gt;, &lt;code&gt;same-origin&lt;/code&gt;, &lt;code&gt;strict-origin&lt;/code&gt;, &lt;code&gt;strict-origin-when-cross-origin&lt;/code&gt;, &lt;code&gt;unsafe-url&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Referrer-Policy value. Absent = strict-origin-when-cross-origin; empty string = header omitted.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-license"&gt;license&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Optional offline signed licence (Ed25519), one token per period. Absent, invalid or expired = evaluation/personal mode: the gateway keeps serving; the user badge shows a notice. The private signing key NEVER ships (only publicKey is embedded).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-token"&gt;&lt;/a&gt; &lt;code&gt;token&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Signed licence token: v1.&amp;lt;base64url(JSON claims)&amp;gt;.&amp;lt;base64url(signature)&amp;gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-tokenFile"&gt;&lt;/a&gt; &lt;code&gt;tokenFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Deprecated single-token file. Prefer tokenDir (one token per period). Overridden by GATE_ONE_LICENSE_TOKEN; falls back to &lt;code&gt;token&lt;/code&gt; when unreadable.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-publicKey"&gt;&lt;/a&gt; &lt;code&gt;publicKey&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Ed25519 public key, base64 (raw 32 bytes). Public by design, safe to commit. Legacy single-key form (tokens without kid).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-publicKeys"&gt;&lt;/a&gt; &lt;code&gt;publicKeys&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;kid → Ed25519 public key (base64). Several keys can be valid at once during a rotation; tokens carry their signed kid. An unknown kid is rejected.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Registration/pricing URL shown by the badge.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-tokenDir"&gt;&lt;/a&gt; &lt;code&gt;tokenDir&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Directory holding one signed token per period: every regular file is read (convention licence-&amp;lt;start&amp;gt;-&amp;lt;end&amp;gt;.txt). The active periods are merged (nbf ⇐ now &amp;lt; exp): domains and features are unioned, domainCount and maxReplicas take the maximum. Dropping a file + SIGHUP is enough.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-license-enforce"&gt;&lt;/a&gt; &lt;code&gt;enforce&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;strict&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;What to do when a configured host is not covered by the active licence: info (default, logged), warn (logged as a warning), strict (503 on that host). Eval (no active token) is never blocked.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-authProvider"&gt;authProvider&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Authentication provider. &lt;code&gt;dev&lt;/code&gt; is the embedded loopback-only IdP used for onboarding/tests; &lt;code&gt;http-bridge&lt;/code&gt; is any external service implementing the Gate One HTTP bridge contract (auth-bridge is the reference implementation; a non-conforming service needs an adapter); &lt;code&gt;oidc&lt;/code&gt; is the native Relying Party (discovery, code+PKCE, JWKS, session, logout, MCP resource server); &lt;code&gt;jwt&lt;/code&gt; is a stateless bearer verifier. Absent = legacy oidc + auth-bridge translation, so existing configs are unchanged. The legacy type &lt;code&gt;http&lt;/code&gt; is accepted as a deprecated alias of &lt;code&gt;http-bridge&lt;/code&gt;.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;http-bridge&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt;, &lt;code&gt;oidc&lt;/code&gt;, &lt;code&gt;jwt&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Provider implementation. Default: dev when a dev block is present, oidc when clientId is present, jwt when jwksUrl is present, http-bridge otherwise. &lt;code&gt;http&lt;/code&gt; is a deprecated alias of &lt;code&gt;http-bridge&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-id"&gt;&lt;/a&gt; &lt;code&gt;id&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Unique provider id when declared in authProviders. The legacy authProvider block is normalized to id &amp;#34;default&amp;#34;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-cookieName"&gt;&lt;/a&gt; &lt;code&gt;cookieName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Session cookie name for type oidc. Empty = gate_one_session for the default provider, a provider-scoped name for additional providers.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-baseUrl"&gt;&lt;/a&gt; &lt;code&gt;baseUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Service root for type http-bridge (default &lt;a class="bare" href="http://auth-bridge:3000"&gt;http://auth-bridge:3000&lt;/a&gt;, or AUTH_BRIDGE_URL).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-loginBaseUrl"&gt;&lt;/a&gt; &lt;code&gt;loginBaseUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Public origin of the login service. For dev it hosts the embedded login page, e.g. &lt;a class="bare" href="http://login.demo.localhost:3000"&gt;http://login.demo.localhost:3000&lt;/a&gt; (no path/query).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-loginUrl"&gt;&lt;/a&gt; &lt;code&gt;loginUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Full login page URL. Defaults to loginBaseUrl + /login, then (type http-bridge) the legacy oidc.loginUrl, then baseUrl + /login.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-issuer"&gt;&lt;/a&gt; &lt;code&gt;issuer&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC issuer advertised in MCP protected-resource metadata. Defaults to the legacy oidc.issuer, or loginBaseUrl + /dev for dev.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-cookieDomain"&gt;&lt;/a&gt; &lt;code&gt;cookieDomain&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Shared parent domain of the session cookie (dev), e.g. demo.localhost. Required for dev.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-defaultAppUrl"&gt;&lt;/a&gt; &lt;code&gt;defaultAppUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Application to send a bare visit to THIS provider’s login host root to. Overrides the global defaultAppUrl for this login host. Must be a route host bound to this provider or a host covered by its cookieDomain. Prefer a neutral page rather than one application.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-verifyUrl"&gt;&lt;/a&gt; &lt;code&gt;verifyUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Identity verification endpoint (type http-bridge). Default baseUrl + /auth.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-mcpVerifyUrl"&gt;&lt;/a&gt; &lt;code&gt;mcpVerifyUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;MCP bearer verification endpoint (type http-bridge). Default baseUrl + /auth/mcp.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-healthUrl"&gt;&lt;/a&gt; &lt;code&gt;healthUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Readiness endpoint (type http-bridge). Default baseUrl + /health.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers"&gt;&lt;/a&gt; &lt;code&gt;headers&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider-headers"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maps the identity response headers of an external provider (type http-bridge). Empty = auth-bridge defaults.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-clientId"&gt;&lt;/a&gt; &lt;code&gt;clientId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC client ID (type oidc). The client must be registered at the IdP with the redirect URI below.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-clientSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clientSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the OIDC client secret (type oidc). Absent/empty = public client (PKCE only). Never put the secret in this file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC scopes requested at the authorization endpoint. Default: openid, profile, email.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-redirectUrl"&gt;&lt;/a&gt; &lt;code&gt;redirectUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC callback URL registered at the IdP. Default: loginBaseUrl + /auth/callback.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-roleClaims"&gt;&lt;/a&gt; &lt;code&gt;roleClaims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dot paths in the ID token whose values become roles (default: realm_access.roles, resource_access.&amp;lt;clientId&amp;gt;.roles, groups).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-scopesClaim"&gt;&lt;/a&gt; &lt;code&gt;scopesClaim&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Claim holding the granted scopes (default scope; scp is always also read).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-mcpAudience"&gt;&lt;/a&gt; &lt;code&gt;mcpAudience&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;MCP access-token audience policy. Empty = scope-only (compatible default). A literal value requires that value in aud. &amp;#34;auto&amp;#34; requires the endpoint’s own protected-resource identifier (recommended, and used with Keycloak audience mappers).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-jwksUrl"&gt;&lt;/a&gt; &lt;code&gt;jwksUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;JWKS endpoint for type jwt. Required for jwt; the provider never hosts a login page.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-audience"&gt;&lt;/a&gt; &lt;code&gt;audience&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Expected audience for type jwt (empty = no audience check, or the MCP resource when VerifyMCP is used).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-algorithms"&gt;&lt;/a&gt; &lt;code&gt;algorithms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Accepted JWT signing algorithms. Default: the algorithms advertised by the JWKS/issuer.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-header"&gt;&lt;/a&gt; &lt;code&gt;header&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Bearer header name for type jwt. Default Authorization.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-cacheTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;cacheTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;JWKS cache TTL for type jwt. Default 300. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;sessionTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC RP session lifetime. Default 3600 (1h): a short TTL bounds revocation when no shared store is used. The refresh/reauth flow renews it. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-links"&gt;&lt;/a&gt; &lt;code&gt;links&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider-links"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Links owned by the authentication connector, displayed in the user badge. account is the IdP’s own account console: NO OIDC standard, so the URL is explicit (Keycloak /realms/&amp;lt;realm&amp;gt;/account/, Entra myaccount.microsoft.com, Google myaccount.google.com, Okta /enduser/settings…).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionKeyEnv"&gt;&lt;/a&gt; &lt;code&gt;sessionKeyEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the RP cookie signing key (base64/random string, hashed to 32 bytes). Empty = the key is generated and persisted in the bbolt store. Required for multi-instance (shared key).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore"&gt;&lt;/a&gt; &lt;code&gt;sessionStore&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider-sessionStore"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;RP-side revocation store (back-channel logout, RP logout). Default: bbolt at ./gate-one-state.db, relative to the config file. bbolt is single-writer: a second Gate One instance on the same file is refused. Redis is the shared, multi-instance backend and makes revocation visible on the next request on every instance.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-backchannelLogout"&gt;&lt;/a&gt; &lt;code&gt;backchannelLogout&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC Back-Channel Logout. Absent = auto: enabled when the IdP discovery advertises backchannel_logout_supported. false disables it. Register &amp;lt;loginBaseUrl&amp;gt;/backchannel-logout at the IdP.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-legacyTokenCookies"&gt;&lt;/a&gt; &lt;code&gt;legacyTokenCookies&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Migration bridge: also set auth-bridge’s access_token/refresh_token/id_token cookies on cookieDomain, so auth-bridge’s token-broker proxy routes (/connections, /connect, /oauth) resolve the same session when both share the login host. Default false. The native session cookie remains authoritative for Gate One.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-backchannelForwardUrl"&gt;&lt;/a&gt; &lt;code&gt;backchannelForwardUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Migration bridge: after a valid local back-channel revocation, POST the same logout_token to this auth-bridge /backchannel-logout URL so its persistent sid list stays in sync for /auth and /connections. Best effort.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-revocationTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;revocationTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Retention of revocation entries. Default: the issuer’s advertised refresh-token TTL (cladone_refresh_token_ttl_seconds, e.g. the embedded IAM), else 30 days; never shorter than the session TTL. Must cover the refresh-token lifetime for a global logout. A revocation covers only sessions/tokens issued before it, so a later sign-in is accepted (a user is never locked out by their own logout). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev"&gt;&lt;/a&gt; &lt;code&gt;dev&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider-dev"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Embedded development IdP. Loopback-only; never production.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-authProvider-headers"&gt;authProvider.headers&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Maps the identity response headers of an external provider (type http-bridge). Empty = auth-bridge defaults.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-userId"&gt;&lt;/a&gt; &lt;code&gt;userId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-User-Id.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-Username.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-email"&gt;&lt;/a&gt; &lt;code&gt;email&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-Email.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-Roles (comma-separated).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-Scopes (comma-separated).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-headers-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default X-Claims (base64 JSON).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-authProvider-links"&gt;authProvider.links&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Links owned by the authentication connector, displayed in the user badge. account is the IdP’s own account console: NO OIDC standard, so the URL is explicit (Keycloak /realms/&amp;lt;realm&amp;gt;/account/, Entra myaccount.microsoft.com, Google myaccount.google.com, Okta /enduser/settings…).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-links-account"&gt;&lt;/a&gt; &lt;code&gt;account&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-authProvider-links-account"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-authProvider-links-account"&gt;authProvider.links.account&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-links-account-label"&gt;&lt;/a&gt; &lt;code&gt;label&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Displayed text. Optional for the connector links (default Account/Services); required for userBadge.links. Maximum length: 64.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-links-account-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;http(s) absolute URL or local absolute path (/…​). Maximum length: 2048.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-links-account-target"&gt;&lt;/a&gt; &lt;code&gt;target&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;_blank&lt;/code&gt;, &lt;code&gt;_self&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Link target. Default _blank.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-authProvider-sessionStore"&gt;authProvider.sessionStore&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;RP-side revocation store (back-channel logout, RP logout). Default: bbolt at ./gate-one-state.db, relative to the config file. bbolt is single-writer: a second Gate One instance on the same file is refused. Redis is the shared, multi-instance backend and makes revocation visible on the next request on every instance.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;bolt&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;bolt (default, single instance) or redis (shared, multi-instance, immediate revocation).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;bbolt file path. Default ./gate-one-state.db (relative to the config file).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis URL for type redis (redis:// or rediss://). Mutually exclusive with sentinel mode.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-sentinelAddrs"&gt;&lt;/a&gt; &lt;code&gt;sentinelAddrs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis Sentinel addresses (host:port). Required with masterName.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-masterName"&gt;&lt;/a&gt; &lt;code&gt;masterName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis Sentinel master name. Requires sentinelAddrs.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-sentinelUsername"&gt;&lt;/a&gt; &lt;code&gt;sentinelUsername&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;ACL user used to authenticate to the Sentinels themselves (sentinel mode only). Separate from username, which is the Redis data user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-sentinelPasswordEnv"&gt;&lt;/a&gt; &lt;code&gt;sentinelPasswordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Sentinel password (sentinel mode only). Never put the password in this file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-tls"&gt;&lt;/a&gt; &lt;code&gt;tls&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Use TLS in sentinel mode (Sentinels and the discovered master). In URL mode use a rediss:// URL instead.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-tlsCaFile"&gt;&lt;/a&gt; &lt;code&gt;tlsCaFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;PEM CA bundle for the Sentinel TLS connections. Requires tls=true; empty = system roots.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-tlsServerName"&gt;&lt;/a&gt; &lt;code&gt;tlsServerName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;TLS server name override (useful when the Sentinels are addressed by IP). Requires tls=true.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis ACL username.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-passwordEnv"&gt;&lt;/a&gt; &lt;code&gt;passwordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Redis password. Never put the password in this file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-db"&gt;&lt;/a&gt; &lt;code&gt;db&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis logical database. Default 0. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-prefix"&gt;&lt;/a&gt; &lt;code&gt;prefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Shared revocation key prefix. Default cladone:auth:v1:. Must match the embedded IAM’s redis.authPrefix.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-dialTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;dialTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis dial timeout in milliseconds. Default 500. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-readTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;readTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis read timeout in milliseconds. Default 300. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-writeTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;writeTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis write timeout in milliseconds. Default 300. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-sessionStore-poolSize"&gt;&lt;/a&gt; &lt;code&gt;poolSize&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis connection pool size. Default 64. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-authProvider-dev"&gt;authProvider.dev&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Embedded development IdP. Loopback-only; never production.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users"&gt;&lt;/a&gt; &lt;code&gt;users&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-authProvider-dev-users"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Development users exposed by the embedded login form. Loopback only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-sessionTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;sessionTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Session lifetime. Default 43200 (12h). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-authProvider-dev-users"&gt;authProvider.dev.users&lt;/h5&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Login name for the development user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-password"&gt;&lt;/a&gt; &lt;code&gt;password&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Plaintext, dev only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Roles granted to this development user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OAuth scopes granted to this development user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to any&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Additional claims returned for this development user (string values).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authProvider-dev-users-mcpToken"&gt;&lt;/a&gt; &lt;code&gt;mcpToken&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Bearer accepted by MCP routes. Default dev-&amp;lt;username&amp;gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-oidc"&gt;oidc&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;LEGACY platform IdP block. When authProvider is absent, it is translated into an http provider (auth-bridge) at load; existing configs keep working. New configurations should use authProvider.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-oidc-loginUrl"&gt;&lt;/a&gt; &lt;code&gt;loginUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Platform login page (e.g. &amp;#34;https://login.example.com/login&amp;#34;). Used by the server-side redirect of frontend routes and by the guard script (per-route authGuard.loginUrl takes precedence).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-oidc-issuer"&gt;&lt;/a&gt; &lt;code&gt;issuer&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC issuer (e.g. &amp;#34;https://auth.example.com/realms/example&amp;#34;) — announced as the authorization_server of the MCP OAuth metadata.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-tokenBroker"&gt;tokenBroker&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Internal per-user credential broker. Required when a route declares upstream.tokenBroker; a configured block also keeps the Services page (/connections: pause/resume/erase) available when no route delegates. The shared secret is read from the named environment variable at load (never from this file) and is never logged.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Broker base URL (default &lt;a class="bare" href="http://token-broker:4000"&gt;http://token-broker:4000&lt;/a&gt;, the Docker internal service name). Never expose it through an ingress: the broker is an internal service.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-secretEnv"&gt;&lt;/a&gt; &lt;code&gt;secretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the X-Broker-Secret shared secret (default TOKEN_BROKER_SHARED_SECRET).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-links"&gt;&lt;/a&gt; &lt;code&gt;links&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-tokenBroker-links"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Links owned by the token broker, displayed in the user badge. services is the services/connections page; it is rendered whenever the broker is configured (the gateway computes the final list at load).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-browserHost"&gt;&lt;/a&gt; &lt;code&gt;browserHost&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Host on which Gate One serves the token broker’s browser routes (/connections, /connect/&lt;strong&gt;, /oauth/&lt;/strong&gt;/callback), authenticating the user and injecting the identity. Empty = derived from links.services.url (its hostname). If both are absent, Gate One does not serve them; an ingress must never proxy those paths directly to the broker (it would answer 401). auth-bridge does not receive the shared secret.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-tokenBroker-links"&gt;tokenBroker.links&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Links owned by the token broker, displayed in the user badge. services is the services/connections page; it is rendered whenever the broker is configured (the gateway computes the final list at load).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-links-services"&gt;&lt;/a&gt; &lt;code&gt;services&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-tokenBroker-links-services"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-tokenBroker-links-services"&gt;tokenBroker.links.services&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-links-services-label"&gt;&lt;/a&gt; &lt;code&gt;label&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Displayed text. Optional for the connector links (default Account/Services); required for userBadge.links. Maximum length: 64.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-links-services-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;http(s) absolute URL or local absolute path (/…​). Maximum length: 2048.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tokenBroker-links-services-target"&gt;&lt;/a&gt; &lt;code&gt;target&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;_blank&lt;/code&gt;, &lt;code&gt;_self&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Link target. Default _blank.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-mcpDefaults"&gt;mcpDefaults&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Optional defaults shared by every MCP access unit.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpDefaults-scope"&gt;&lt;/a&gt; &lt;code&gt;scope&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default MCP scope when a service/set declares none.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-mcpSets"&gt;mcpSets&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;An MCP access unit grouping services under one endpoint; carries the audience (resource), scope and identity of the group.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-host"&gt;&lt;/a&gt; &lt;code&gt;host&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Public host serving the set.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-endpoint"&gt;&lt;/a&gt; &lt;code&gt;endpoint&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Mount path of the set on that host (&amp;#34;/&amp;#34; allowed).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-resource"&gt;&lt;/a&gt; &lt;code&gt;resource&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OAuth protected-resource identifier (audience) of the set. Empty = the set endpoint URL.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-scope"&gt;&lt;/a&gt; &lt;code&gt;scope&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;MCP scope required from clients of this set. Default: mcpDefaults.scope, else mcp-tools.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-identity"&gt;&lt;/a&gt; &lt;code&gt;identity&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-mcpSets-identity"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Identity policy conditions, evaluated AFTER authentication on the verified token (failure = 403 forbidden). All conditions combine with AND.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Expose the set (default true). false = the whole set is skipped (no endpoint, no validation).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-members"&gt;&lt;/a&gt; &lt;code&gt;members&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-mcpSets-members"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-mcpSets-identity"&gt;mcpSets.identity&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Identity policy conditions, evaluated AFTER authentication on the verified token (failure = 403 forbidden). All conditions combine with AND.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-identity-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required Keycloak roles (realm roles + flattened client roles, see auth-bridge’s X-Roles). AND between them. Example of a fixed name: offline_access (realm role granted to every user via default-roles-&amp;lt;realm&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-identity-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required granted scopes (token &lt;code&gt;scope&lt;/code&gt; claim, see auth-bridge’s X-Scopes). AND between them. Example of a fixed name: profile (default client scope, always present).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-identity-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Token claims: key = claim name, value = one accepted string or a list of accepted strings (OR / anyOf on the same claim). &amp;#34;*&amp;#34; = the claim is present. All keys combine with AND. A token claim that is itself a list (groups, roles…) matches when one of its elements matches. Example: {&amp;#34;email&amp;#34;: [&amp;#34;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&amp;#34;, &amp;#34;&lt;a href="mailto:a.rolland@example.com"&gt;a.rolland@example.com&lt;/a&gt;&amp;#34;], &amp;#34;email_verified&amp;#34;: &amp;#34;true&amp;#34;}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-identity-user"&gt;&lt;/a&gt; &lt;code&gt;user&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact username required (preferred_username).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-mcpSets-members"&gt;mcpSets.members&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One service mounted under a set.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-members-service"&gt;&lt;/a&gt; &lt;code&gt;service&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;mcp.name of the referenced service.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-members-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path relative to the set endpoint (&amp;#34;/&amp;#34; = the set endpoint itself).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-members-tools"&gt;&lt;/a&gt; &lt;code&gt;tools&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional glob allow-list restricting the service’s tools inside this set.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpSets-members-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Expose this member (default true). false = not materialized, and its service is neither compiled (no OpenAPI fetch) nor provider-validated.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-publisherFeed"&gt;publisherFeed&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Optional signed publisher feed: compatible Gate One versions, external components and plugins, with their revocation status. Loaded and verified at startup; the operator’s trust store stays authoritative. Absent = no feed is consulted.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publisherFeed-file"&gt;&lt;/a&gt; &lt;code&gt;file&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Feed path, relative to the config file. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publisherFeed-keys"&gt;&lt;/a&gt; &lt;code&gt;keys&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Feed signing keys: key id → base64 Ed25519 public key. The feed’s signature key id must be present. Provisioned out-of-band.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publisherFeed-mode"&gt;&lt;/a&gt; &lt;code&gt;mode&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;warn&lt;/code&gt;, &lt;code&gt;enforce&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;warn (default): report revocations and incompatibilities only. enforce: apply the feed’s revocations (digest and key) to the plugin trust store, so a revoked plugin refuses to load.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-turnstile"&gt;turnstile&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Platform-wide Cloudflare Turnstile bot check for form pages. Presence enables it (explicit enabled=false disables it in templated configs). The widget is injected into matching HTML pages and every matching request is verified against the Siteverify API BEFORE the backend: a missing/invalid token is answered 403 (readable page for a navigation, JSON otherwise), a Siteverify outage 503 (fail closed). The block is global on purpose: one place to change, no per-host duplication. LIMITATION: it protects only traffic that passes through this Gate One instance; a second ingress, an internal caller or a direct port reaching the application bypasses it. Network isolation (only Gate One can reach the application) remains required. The token is never logged nor written to usage events.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Explicit switch for templated configurations. Absent = enabled when the block is present.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-mode"&gt;&lt;/a&gt; &lt;code&gt;mode&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;forms&lt;/code&gt;, &lt;code&gt;gate&lt;/code&gt;, &lt;code&gt;both&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Protection mode. forms: inject the widget into forms and verify the configured methods. gate: challenge the first request to a protected path, set a signed clearance cookie (clearanceTtlSeconds) and let the following requests through without a new Siteverify call; a form POST without clearance is refused (the submitted data cannot be replayed), an API/fetch call gets 403 turnstile_required. both: gate AND form verification. Default forms.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-siteKey"&gt;&lt;/a&gt; &lt;code&gt;siteKey&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Public Turnstile site key (safe in the page). Cloudflare binds it to a domain list: every public hostname serving the form must be declared there. Minimum length: 1. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-secretEnv"&gt;&lt;/a&gt; &lt;code&gt;secretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Name of the environment variable holding the Turnstile secret key. Required: the secret is only read from the environment, never from this file, and never sent to the browser. Missing/empty variable refuses startup. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-hosts"&gt;&lt;/a&gt; &lt;code&gt;hosts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Hosts the block applies to: exact hostnames, or a leading &lt;strong&gt;. wildcard on a label boundary (&lt;/strong&gt;.example.com). Empty = every route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-paths"&gt;&lt;/a&gt; &lt;code&gt;paths&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Paths the block applies to, with the route.path grammar: /contact/* (prefix on a path boundary), an exact path, or /* (everything). Empty = every path. The widget is injected only on matching pages; verification only on matching requests.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-methods"&gt;&lt;/a&gt; &lt;code&gt;methods&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string (one of: &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Request methods verified. Default POST. GET/HEAD are never challenged (the page must load before the widget can run).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-forms"&gt;&lt;/a&gt; &lt;code&gt;forms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;CSS selectors of the forms that receive the widget. Empty = every POST form on the page. A form marked data-gtw-turnstile=&amp;#34;off&amp;#34; is always skipped. An invalid selector is ignored (no injection, no error).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-action"&gt;&lt;/a&gt; &lt;code&gt;action&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional action sent with the widget and required in the Siteverify answer (1-32 letters, digits, _ or -). Binds the token to this form: a token obtained for another action is refused. Pattern: &lt;code&gt;^[A-Za-z0-9_-]{1,32}$&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-hostname"&gt;&lt;/a&gt; &lt;code&gt;hostname&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional expected hostname in the Siteverify answer. Empty = no check (the site key’s domain list already constrains it). Useful when one site key serves several hosts and each must be pinned.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-tokenHeader"&gt;&lt;/a&gt; &lt;code&gt;tokenHeader&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Header accepted in addition to the cf-turnstile-response form field, for fetch/SPA clients. Default X-Turnstile-Response. The injected script attaches the token to same-origin mutating fetches automatically. Pattern: &lt;code&gt;^[A-Za-z0-9-]+$&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-exemptPaths"&gt;&lt;/a&gt; &lt;code&gt;exemptPaths&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Paths never gated in gate/both mode (machine endpoints, webhooks, MCP). The route.path grammar applies (/api/webhooks/&lt;strong&gt;, exact path). Built-in exemptions always apply: /healthz, /readyz, /__gate-one/&lt;/strong&gt;, /favicon.ico, /robots.txt. OPTIONS requests are never gated.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-clearanceTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;clearanceTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Lifetime of the gate clearance cookie. Default 1800 (30 minutes). A visitor who solved the challenge is not challenged again before it expires; rotating the signing key invalidates every clearance. Minimum: 60. Maximum: 604800.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-clearanceSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clearanceSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the HMAC key that signs the clearance cookie. Optional: when empty, the key is derived from the Turnstile secret with domain separation (rotating that secret then invalidates every clearance). A dedicated key lets you rotate clearances without touching the widget secret. Must be identical on every replica.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-challenge"&gt;&lt;/a&gt; &lt;code&gt;challenge&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-turnstile-challenge"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Challenge page tuning (gate/both).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-preclearance"&gt;&lt;/a&gt; &lt;code&gt;preclearance&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;gate/both: the injected script solves the challenge in the background when a page is served without clearance, so the first user action needs a single backend call. Default true. The 403 turnstile_required + replay remains the fallback.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-turnstile-challenge"&gt;turnstile.challenge&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Challenge page tuning (gate/both).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-turnstile-challenge-appearance"&gt;&lt;/a&gt; &lt;code&gt;appearance&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;always&lt;/code&gt;, &lt;code&gt;execute&lt;/code&gt;, &lt;code&gt;interaction-only&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Turnstile render appearance of the challenge widget. Default interaction-only in gate/both: the widget stays hidden unless Cloudflare requires an interaction. always shows it; execute renders without running the challenge until executed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-usage"&gt;usage&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Out-of-process usage-event bus (WAL + extension plugins). Presence enables it. Events are produced only for the subscribed types; a full durable share is answered with a targeted 503 (health/readyz/auth-probe exempt).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-dir"&gt;&lt;/a&gt; &lt;code&gt;dir&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;WAL directory (one subdirectory per event type). Relative paths are resolved from the config file. Default ./gate-one-usage.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-nodeId"&gt;&lt;/a&gt; &lt;code&gt;nodeId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Instance identifier written in every event. Default: hostname.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-subjectSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;subjectSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the HMAC key deriving the opaque subjectId. Required.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-pluginSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;pluginSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the HMAC key signing host→plugin assertions. Required.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-budgetBytes"&gt;&lt;/a&gt; &lt;code&gt;budgetBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Node WAL budget in bytes, split across the type shares. Default 52428800 (50 MiB). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-trustStore"&gt;&lt;/a&gt; &lt;code&gt;trustStore&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path of the signed plugin trust store (JSON: keys, allowedNames, allowedDependencies, revokedDigests, allowAuth, coreVersion). Required when a plugin declares a signed manifest. Relative paths are resolved from the config file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-requireSigned"&gt;&lt;/a&gt; &lt;code&gt;requireSigned&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Refuse any plugin without a signed manifest. Default false: an unsigned plugin is allowed for development and logged as a warning.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-pluginsDir"&gt;&lt;/a&gt; &lt;code&gt;pluginsDir&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Directory scanned for plugin descriptors: every *.json file is a plugin entry (same shape as usage.plugins[]). Manifest and artifact paths are relative to the descriptor. Merged with usage.plugins; duplicate names are refused. Rescanned on SIGHUP.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-types"&gt;&lt;/a&gt; &lt;code&gt;types&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-usage-types"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Durable event type → WAL policy. A plugin can only subscribe to a configured type.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture"&gt;&lt;/a&gt; &lt;code&gt;capture&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-usage-capture"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Opt-in capture of allow-listed query parameters and JSON body fields into matching events (default: billing). Scoped by host/route/method; values are capped and sensitive names skipped.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-profile"&gt;&lt;/a&gt; &lt;code&gt;profile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;online&lt;/code&gt;, &lt;code&gt;airgap&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Spending authorisation profile: online (a lease refilled from the managed ledger) or airgap (a signed allowance file, valid for a period). Default online. The airgap profile bypasses the managed settlement split and therefore requires the &amp;#34;billing-byo&amp;#34; licence feature; the gateway refuses to start without it.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics"&gt;&lt;/a&gt; &lt;code&gt;metrics&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-usage-metrics"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Billable metrics, keyed by metric code. A route references one with routes[].metric. Empty = the metering path is disabled.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs"&gt;&lt;/a&gt; &lt;code&gt;tariffs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-usage-tariffs"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Versioned rate tables, keyed by version. Each entry names its metric and effective date.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox"&gt;&lt;/a&gt; &lt;code&gt;outbox&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-usage-outbox"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Bounded local delivery buffer for billing records. It survives a transport outage for a few hours, then refuses new billable requests; it is not a financial archive.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink"&gt;&lt;/a&gt; &lt;code&gt;sink&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-usage-sink"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Delivery of billing records: signed push to the managed endpoint, or a signed export bundle when the endpoint is unreachable (airgap).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-allowanceFile"&gt;&lt;/a&gt; &lt;code&gt;allowanceFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Signed allowance file (airgap profile). Resolved relative to the configuration file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-allowanceEnv"&gt;&lt;/a&gt; &lt;code&gt;allowanceEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the signed allowance JSON. Mutually exclusive with allowanceFile.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-allowancePublicKey"&gt;&lt;/a&gt; &lt;code&gt;allowancePublicKey&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Base64 Ed25519 public key verifying the allowance (airgap profile).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins"&gt;&lt;/a&gt; &lt;code&gt;plugins&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-usage-plugins"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Out-of-process event consumers (HTTP/JSON), each with its own subscription or signed manifest.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-types"&gt;usage.types&lt;/h4&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-types-shareBytes"&gt;&lt;/a&gt; &lt;code&gt;shareBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum size of this type’s WAL on this node. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-types-fsync"&gt;&lt;/a&gt; &lt;code&gt;fsync&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;none&lt;/code&gt;, &lt;code&gt;window_ms&lt;/code&gt;, &lt;code&gt;always&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Durability: none, group commit every windowMs, or fsync before the response (zero_loss). always is refused for request/error (the proxy emitter cannot fsync before a streaming response).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-types-windowMs"&gt;&lt;/a&gt; &lt;code&gt;windowMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Group-commit interval for fsync=window_ms. Default 100. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-types-segmentBytes"&gt;&lt;/a&gt; &lt;code&gt;segmentBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Append-file rotation size. 0 = share/4 capped at 8 MiB. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-capture"&gt;usage.capture&lt;/h4&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-hosts"&gt;&lt;/a&gt; &lt;code&gt;hosts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Request hosts or glob patterns to capture. Empty = all hosts.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-routes"&gt;&lt;/a&gt; &lt;code&gt;routes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Request path patterns to capture. Empty = all paths.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-methods"&gt;&lt;/a&gt; &lt;code&gt;methods&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP methods to capture. Empty = all methods.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-types"&gt;&lt;/a&gt; &lt;code&gt;types&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Event types to attach attrs to. Default: [billing].&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-query"&gt;&lt;/a&gt; &lt;code&gt;query&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allow-listed query parameter names whose values are copied as q.&amp;lt;name&amp;gt;. Sensitive names are skipped.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-body"&gt;&lt;/a&gt; &lt;code&gt;body&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-usage-capture-body"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional JSON-body extraction.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-maxAttrsBytes"&gt;&lt;/a&gt; &lt;code&gt;maxAttrsBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Total attrs budget in bytes. Default 1024, clamped to 2048. Minimum: 0. Maximum: 2048.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-usage-capture-body"&gt;usage.capture.body&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Optional JSON-body extraction.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-body-format"&gt;&lt;/a&gt; &lt;code&gt;format&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;json&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Body parser; only json is supported.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-body-paths"&gt;&lt;/a&gt; &lt;code&gt;paths&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dotted JSON paths ($.a.b or a.b) whose scalar values are copied as b.&amp;lt;path&amp;gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-capture-body-maxBytes"&gt;&lt;/a&gt; &lt;code&gt;maxBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Skip body capture when the raw body is larger. 0 = no limit. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-metrics"&gt;usage.metrics&lt;/h4&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-unit"&gt;&lt;/a&gt; &lt;code&gt;unit&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Free-form unit label (request, token, byte, second, …​). Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-scale"&gt;&lt;/a&gt; &lt;code&gt;scale&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer (one of: &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;6&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Decimal scale of the quantity: 0 (units), 3 (milli) or 6 (micro).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-maxDimensions"&gt;&lt;/a&gt; &lt;code&gt;maxDimensions&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum number of dimensions accepted per measure; must not exceed the declared dimensions. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-dimensions"&gt;&lt;/a&gt; &lt;code&gt;dimensions&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-usage-metrics-dimensions"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Declared dimension names and their types; an undeclared dimension is rejected.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-measurement"&gt;&lt;/a&gt; &lt;code&gt;measurement&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;event&lt;/code&gt;, &lt;code&gt;periodic&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;event (discrete fact) or periodic (continuous quantity emitted by heartbeat, e.g. time, bytes, storage). Default event.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-heartbeatSeconds"&gt;&lt;/a&gt; &lt;code&gt;heartbeatSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Heartbeat period of a periodic metric. Default 60. Minimum: 10. Maximum: 3600.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-pricing"&gt;&lt;/a&gt; &lt;code&gt;pricing&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;declarative&lt;/code&gt;, &lt;code&gt;plugin&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;declarative (core rate table) or plugin (signed pricing plugin). Default declarative.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-fallback"&gt;&lt;/a&gt; &lt;code&gt;fallback&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Declarative tariff version used when pricing=plugin is unavailable. Required with pricing=plugin.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-usage-metrics-dimensions"&gt;usage.metrics.dimensions&lt;/h5&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-dimensions-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;enum&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-dimensions-maxLength"&gt;&lt;/a&gt; &lt;code&gt;maxLength&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-metrics-dimensions-values"&gt;&lt;/a&gt; &lt;code&gt;values&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-tariffs"&gt;usage.tariffs&lt;/h4&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-metric"&gt;&lt;/a&gt; &lt;code&gt;metric&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-version"&gt;&lt;/a&gt; &lt;code&gt;version&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-currency"&gt;&lt;/a&gt; &lt;code&gt;currency&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum length: 3. Maximum length: 3.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-effectiveFrom"&gt;&lt;/a&gt; &lt;code&gt;effectiveFrom&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges"&gt;&lt;/a&gt; &lt;code&gt;charges&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-usage-tariffs-charges"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-usage-tariffs-charges"&gt;usage.tariffs.charges&lt;/h5&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-model"&gt;&lt;/a&gt; &lt;code&gt;model&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;unit&lt;/code&gt;, &lt;code&gt;tiered&lt;/code&gt;, &lt;code&gt;volume&lt;/code&gt;, &lt;code&gt;package&lt;/code&gt;, &lt;code&gt;percentage_of&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-amountMicro"&gt;&lt;/a&gt; &lt;code&gt;amountMicro&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-filter"&gt;&lt;/a&gt; &lt;code&gt;filter&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-tiers"&gt;&lt;/a&gt; &lt;code&gt;tiers&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-usage-tariffs-charges-tiers"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-packageSize"&gt;&lt;/a&gt; &lt;code&gt;packageSize&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-freeUnits"&gt;&lt;/a&gt; &lt;code&gt;freeUnits&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-rateBasisPoints"&gt;&lt;/a&gt; &lt;code&gt;rateBasisPoints&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-fixedAmountMicro"&gt;&lt;/a&gt; &lt;code&gt;fixedAmountMicro&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect5"&gt;&#10;&lt;h6 id="config-usage-tariffs-charges-tiers"&gt;usage.tariffs.charges.tiers&lt;/h6&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-tiers-fromValue"&gt;&lt;/a&gt; &lt;code&gt;fromValue&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-tiers-toValue"&gt;&lt;/a&gt; &lt;code&gt;toValue&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-tiers-perUnitMicro"&gt;&lt;/a&gt; &lt;code&gt;perUnitMicro&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-tariffs-charges-tiers-flatAmountMicro"&gt;&lt;/a&gt; &lt;code&gt;flatAmountMicro&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-outbox"&gt;usage.outbox&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Bounded local delivery buffer for billing records. It survives a transport outage for a few hours, then refuses new billable requests; it is not a financial archive.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox-dir"&gt;&lt;/a&gt; &lt;code&gt;dir&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Outbox directory. Default ./usage-outbox, resolved from the configuration file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox-maxAge"&gt;&lt;/a&gt; &lt;code&gt;maxAge&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum age of the oldest pending record (duration, e.g. 6h). Default 6h.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox-maxBytes"&gt;&lt;/a&gt; &lt;code&gt;maxBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum pending bytes. Default 512 MiB. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox-maxRecords"&gt;&lt;/a&gt; &lt;code&gt;maxRecords&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum pending records. Default 50000. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-outbox-onFull"&gt;&lt;/a&gt; &lt;code&gt;onFull&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;block&lt;/code&gt;, &lt;code&gt;drop&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;block (default): new billable requests answer 503 when the buffer is full. drop: discard (counted, logged) — never silent but loses revenue.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-sink"&gt;usage.sink&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Delivery of billing records: signed push to the managed endpoint, or a signed export bundle when the endpoint is unreachable (airgap).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Managed ingest endpoint (http/https). Empty = export only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-secretEnv"&gt;&lt;/a&gt; &lt;code&gt;secretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Bearer secret sent with every push.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-signingKeyEnv"&gt;&lt;/a&gt; &lt;code&gt;signingKeyEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the base64url 32-byte Ed25519 seed that signs each batch and each export bundle. Required when metrics are configured.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-batchRecords"&gt;&lt;/a&gt; &lt;code&gt;batchRecords&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum records per batch. Default 500. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-batchBytes"&gt;&lt;/a&gt; &lt;code&gt;batchBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum batch size in bytes. Default 1 MiB. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-batchWaitMs"&gt;&lt;/a&gt; &lt;code&gt;batchWaitMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum wait before flushing a partial batch. Default 1000 ms. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-exportDir"&gt;&lt;/a&gt; &lt;code&gt;exportDir&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Directory receiving signed export bundles (bundle .jsonl, .sig and manifest). Required for the airgap profile.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-exportAfterSeconds"&gt;&lt;/a&gt; &lt;code&gt;exportAfterSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;How long the push may fail before an export bundle is written. Default 300 s. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-sink-receiptPublicKey"&gt;&lt;/a&gt; &lt;code&gt;receiptPublicKey&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Base64 Ed25519 public key of the ingest service, verifies the signed receipts that acknowledge an air-gap bundle (gate-one billing ack). Required for the airgap profile.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-usage-plugins"&gt;usage.plugins&lt;/h4&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Unique plugin name (assertion audience). Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Absolute http(s) base URL. /health and /events are appended.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-manifest"&gt;&lt;/a&gt; &lt;code&gt;manifest&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path of the signed plugin manifest. When set, the manifest is authoritative for the event subscription and the licence feature; artifact is required and usage.trustStore must be configured.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-artifact"&gt;&lt;/a&gt; &lt;code&gt;artifact&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path of the signed plugin artefact (binary/container). Required with manifest; its digest is verified against the manifest.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-types"&gt;&lt;/a&gt; &lt;code&gt;types&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string (one of: &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;billing&lt;/code&gt;, &lt;code&gt;audit&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Subscribed event types when no signed manifest is used; each must be configured in usage.types.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters"&gt;&lt;/a&gt; &lt;code&gt;filters&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-usage-plugins-filters"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Narrow the subscription by host, route, tenant, method, status class or sample rate. Route patterns match the path only, so use hosts to avoid matching the same path on every host.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-maxLagBytes"&gt;&lt;/a&gt; &lt;code&gt;maxLagBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed subscriber lag. Beyond it, onMaxLag applies. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-onMaxLag"&gt;&lt;/a&gt; &lt;code&gt;onMaxLag&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;block&lt;/code&gt;, &lt;code&gt;drop&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;block (default): 503 until catch-up; drop: move the cursor to the lag limit and let eviction proceed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-licenseFeature"&gt;&lt;/a&gt; &lt;code&gt;licenseFeature&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required signed-licence feature; the plugin is refused without it.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-usage-plugins-filters"&gt;usage.plugins.filters&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Narrow the subscription by host, route, tenant, method, status class or sample rate. Route patterns match the path only, so use hosts to avoid matching the same path on every host.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-hosts"&gt;&lt;/a&gt; &lt;code&gt;hosts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Request hosts or glob patterns to include (e.g. app.example.com, *.example.com). Empty = all hosts.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-routes"&gt;&lt;/a&gt; &lt;code&gt;routes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Route patterns to include, for example /api/*. Empty = all routes.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-tenants"&gt;&lt;/a&gt; &lt;code&gt;tenants&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Tenant or auth-provider ids to include. Empty = all tenants.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-methods"&gt;&lt;/a&gt; &lt;code&gt;methods&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP methods to include. Empty = all methods.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-statusClasses"&gt;&lt;/a&gt; &lt;code&gt;statusClasses&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP status classes to include (1xx..5xx). Empty = all classes.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-usage-plugins-filters-sampleRate"&gt;&lt;/a&gt; &lt;code&gt;sampleRate&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;number&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Sampling rate for matching events, 0..1. Default 1.0. Minimum: 0. Maximum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-routes"&gt;routes&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-host"&gt;&lt;/a&gt; &lt;code&gt;host&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Single literal application host (or wildcard pattern when wildcard is set). Mutually exclusive with hosts.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-hosts"&gt;&lt;/a&gt; &lt;code&gt;hosts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Literal application hosts sharing this route body. Expanded at load into one concrete route per host; auth.provider is inferred from the ssoGroups provider whose cookieDomain covers each host. Mutually exclusive with host and wildcard.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-wildcard"&gt;&lt;/a&gt; &lt;code&gt;wildcard&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Named host/backend expansion — one route, N sites. Keys = capture names ({name} in host and backend), values = the ALLOW-LISTS of DNS labels they may take (a-z0-9, hyphens, no dots). The route expands at load into one concrete route per label; a label outside the lists has no route (fail-closed: the backend is never attacker-derived). With rewriteBody enabled, the expansion also compiles the cross-route map: an origin of another variant (e.g. es.wikipedia.org in the English edition) is rewritten to that sibling’s public host; ambiguous alias mappings are left alone, and route-local except prefixes do not apply to siblings.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Prefix; &amp;#34;/*&amp;#34; = wildcard (whole host).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-stripPrefix"&gt;&lt;/a&gt; &lt;code&gt;stripPrefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact PUBLIC path prefix removed from the request before it reaches the backend. Path only (no query, fragment or wildcard), matched on segment boundaries and normalized at load (trailing slash removed; root &amp;#34;/&amp;#34; forbidden). Example: path &amp;#34;/api/*&amp;#34;, stripPrefix &amp;#34;/api&amp;#34;, backend &amp;#34;http://api:8080/v1&amp;#34; turns /api/foo into /v1/foo. The backend also receives X-Forwarded-Prefix when the ingress did not set one. Response paths are rewritten symmetrically: Location, Content-Location, Refresh/Link headers, Set-Cookie Path, and HTML URL attributes (href/src/action/srcset/poster, style url(), meta refresh) are brought back under /api; relative references and other origins are left untouched. Script strings and CSS @import are out of scope. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-backend"&gt;&lt;/a&gt; &lt;code&gt;backend&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Backend base URL (http/https) that serves the route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-inject"&gt;&lt;/a&gt; &lt;code&gt;inject&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path of the route’s custom injection bundle (JSON), relative to the config file. The bundle declares HTML/JS/CSS insertions by named target (&amp;#34;head&amp;#34; = after &amp;lt;head&amp;gt;/meta charset, &amp;#34;body-end&amp;#34; = before &amp;lt;/body&amp;gt;) with per-page targeting (when = path prefix) and data-* attribute patches applied client-side by the guard. Inline content or file: (relative to the bundle, read at load — a faulty bundle refuses startup). Its formal grammar is inject-bundle.schema.json. See the doc’s § upstream.inject.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream"&gt;&lt;/a&gt; &lt;code&gt;upstream&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Join to a backend outside the internal network (proxified external site — e.g. Cloudflare Pages/Workers). Absent = unchanged historical behavior: public Host preserved, client headers passed as-is.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-frontend"&gt;&lt;/a&gt; &lt;code&gt;frontend&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Page route: auth failure → 302 to the login (API routes get a JSON 401); eligible for the guard script and the pwa policy.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-usage"&gt;&lt;/a&gt; &lt;code&gt;usage&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Emit usage events for this route. Default true; set false to serve the route without producing ANY usage event — no WAL reservation and no admission 503 on this route. Use it for control or monitoring routes (a status page, an events viewer) that must not pollute, or depend on, the event bus.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-metric"&gt;&lt;/a&gt; &lt;code&gt;metric&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Billable metric produced by this route (a key of usage.metrics). The amount is rated and reserved BEFORE the backend call; an unaffordable request answers 402 instead of running. Empty = the route does not use the metering path.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-autoHead"&gt;&lt;/a&gt; &lt;code&gt;autoHead&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HEAD requests are served as GET, body removed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth"&gt;&lt;/a&gt; &lt;code&gt;auth&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-auth"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Authentication policy. Empty ({}) = authentication ALWAYS required. auth.when holds TECHNICAL conditions (method/query/header/body) deciding when authentication is required: one object (AND of its conditions) or an array (OR of ANDs — required if ANY element matches); absent/empty = always required. auth.identity holds IDENTITY conditions (roles/scopes/claims/user), checked after successful authentication (403 otherwise) and only on requests that were actually authenticated.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit"&gt;&lt;/a&gt; &lt;code&gt;rateLimit&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-rateLimit"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rate limiting: fixed window per identity (authenticated user, else real IP via X-Forwarded-For), per route. Full window = 429 + Retry-After (seconds). Periods: second|minute|hour|day.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota"&gt;&lt;/a&gt; &lt;code&gt;quota&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-quota"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Cumulative quota: same mechanics as rateLimit with a longer window in practice (day). Full window = 429 + Retry-After.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-openapi"&gt;&lt;/a&gt; &lt;code&gt;openapi&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-openapi"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OpenAPI document used to derive REST operations and MCP tools for this route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp"&gt;&lt;/a&gt; &lt;code&gt;mcp&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-mcp"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Expose a route as an MCP service: protected-resource identifier, scope, tools and metadata.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa"&gt;&lt;/a&gt; &lt;code&gt;pwa&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-pwa"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;PWA shell, manifest, icons and service-worker cache policy for a frontend route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp"&gt;&lt;/a&gt; &lt;code&gt;csp&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-csp"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Content-Security-Policy emitted (or amended) by the gateway — the only component able to generate a per-response nonce and write it into the HTML it already rewrites (guard, PWA, custom injections). By default the origin’s policy is NEVER removed or weakened: the gateway’s policy is added as a SECOND header (browsers enforce all of them, so the effective rule is the strictest) and the hashes of the gateway’s own injected script and guard stylesheet are APPENDED to the origin’s script-src / style-src (script-src-elem &amp;gt; script-src &amp;gt; default-src, style-src-elem &amp;gt; style-src &amp;gt; default-src). Set own=true to remove the origin policy explicitly and let the gateway own it (opt-in, logged, requires mode nonce/hash and reportOnly=false). Applied to HTML responses only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge"&gt;&lt;/a&gt; &lt;code&gt;userBadge&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-userBadge"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;User badge injected by the guard script once authenticated: collapsed on the top edge (one line = username), expanded on hover/keyboard focus — chosen claims + logout button (OIDC end_session + cookie clearing). Absent = no badge.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate"&gt;&lt;/a&gt; &lt;code&gt;uiGate&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-routes-uiGate"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;UI gating by config (CSS selectors) — embedded in the injected guard script. Only for non-modifiable fronts; an element’s data-gtw-* markup wins over the rules.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard"&gt;&lt;/a&gt; &lt;code&gt;authGuard&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-authGuard"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;401 guard script (login without reloading: tab + replay + banner + declarative gating). Active by default on frontend routes; no-op elsewhere. The guard intercepts the 401 (login) and, when authGuard.forbidden.banner is set, the gateway’s OWN identity 403; a 403 coming from the backend is never concerned.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-upstream"&gt;routes.upstream&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Join to a backend outside the internal network (proxified external site — e.g. Cloudflare Pages/Workers). Absent = unchanged historical behavior: public Host preserved, client headers passed as-is.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-host"&gt;&lt;/a&gt; &lt;code&gt;host&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;true = the Host header sent to the backend is that of the backend’s origin (required for an external site that routes by Host, e.g. Cloudflare — otherwise the request arrives with the public host and the origin does not recognize it). Absent/false = public Host passed as-is (internal backends). TLS/SNI always targets the backend’s origin.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-hostOverride"&gt;&lt;/a&gt; &lt;code&gt;hostOverride&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Explicit value of the Host header sent to the backend, when it must differ from both the public host and the backend’s origin (rare). Precedence over host.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-headers"&gt;&lt;/a&gt; &lt;code&gt;headers&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Static request headers set toward the backend (Set: overwrite any value the client may have sent). Uses: get through an origin basic auth (&amp;#34;Authorization&amp;#34;: &amp;#34;Basic ${MYSITE_BASIC_AUTH}&amp;#34;) or the Cloudflare Access service tokens (CF-Access-Client-Id / CF-Access-Client-Secret). Values with ${VAR} interpolation from the container environment — missing variable = fatal error at load (never a silent empty credential); empty value = header removed from the request. Values are never logged.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteRedirects"&gt;&lt;/a&gt; &lt;code&gt;rewriteRedirects&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;true = ABSOLUTE Locations targeting the backend’s origin are rewritten to the public host (https scheme, path/query preserved) — otherwise the browser would leave the proxy at the target site’s first absolute redirect (e.g. 301 of the trailing slash). Relative Locations and those targeting other origins (e.g. a Cloudflare Access team domain) pass intact. Default: false.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-responseHeaders"&gt;&lt;/a&gt; &lt;code&gt;responseHeaders&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream-responseHeaders"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Adjustment of the backend’s RESPONSE headers before sending to the browser — typically remove an origin Content-Security-Policy that would block the injected guard script, or set a deployment header. Prefer csp.merge (hashes) or csp.own (explicit removal, logged) for CSP: removing the origin’s CSP here is a blunt, unlogged operation and loses the origin’s protections.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteBody"&gt;&lt;/a&gt; &lt;code&gt;rewriteBody&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream-rewriteBody"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rewriting of the HTML body (200 text/html only, STREAMING — O(1) memory): the origin’s absolute URLs cited in the pages (&amp;#34;https://origin/…&amp;#34;, &amp;#34;http://origin/…&amp;#34;, &amp;#34;//origin/…&amp;#34;) are rewritten to the route’s public host, so the browser stays in the proxy. Any explicit port is part of the rewritten prefix and is lost (target served on the standard port). The path, query and fragment follow as-is. Routes expanded from one wildcard automatically rewrite sibling editions toward their public hosts. &lt;code&gt;targets&lt;/code&gt; and &lt;code&gt;followRoutes&lt;/code&gt; add explicit cross-route mappings (bare hosts only: the request’s scheme and port are inherited). At runtime (fetch/XHR/sendBeacon launched by the site), the client SW served on /__gate-one_pwa/sw.js applies the same policy — it is auto-registered by the guard script, served pre-authentication. One same policy (origins × exceptions × targets) is implemented three times (Go engine, client SW, script patch) — parity tested. Default: absent (no body rewriting).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteCookies"&gt;&lt;/a&gt; &lt;code&gt;rewriteCookies&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream-rewriteCookies"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Translation of the Set-Cookie set by the origin: a Domain attribute targeting its own namespace (&amp;#34;Domain=original…domain.dev&amp;#34;) would be rejected by the browser from the public host — the cookie would be silently lost. Active: a Domain targeting the origin host (equal or parent) is rewritten to the public host in &amp;#34;rewrite&amp;#34; mode (the sharing scope — host + subdomains — is transposed as-is), or the attribute is removed in &amp;#34;strip&amp;#34; mode (host-only on the public host). Other cookies pass intact (surgery of the Domain attribute only: Path/Secure/HttpOnly/SameSite/Expires come out byte-exact). Auth protection: an origin Set-Cookie bearing a name reserved for the gateway session (access_token, refresh_token, id_token, session) is removed with a warning — set on the same public host, it would overwrite the session cookies. Default: absent (no cookie rewriting).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-stripCookies"&gt;&lt;/a&gt; &lt;code&gt;stripCookies&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;all&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;REQUEST-side cookie filtering toward the backend. The gateway session cookies (access_token, refresh_token, id_token, session) carry Domain=&amp;lt;parent domain&amp;gt; (COOKIE_DOMAIN, e.g. .cladone.com): the browser presents them to EVERY public host, so without this filter a proxified third-party site receives the user’s tokens on every request. &amp;#34;all&amp;#34; = every cookie removed except the names in keep (the proxified app’s own cookies); &amp;#34;none&amp;#34; = historical behavior, everything forwarded. Default: &amp;#34;all&amp;#34; as soon as an upstream policy is declared (fail-closed).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-keep"&gt;&lt;/a&gt; &lt;code&gt;keep&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Cookie names preserved when stripCookies is &amp;#34;all&amp;#34; (typically the proxified application’s own session). Names reserved for the gateway session (access_token, refresh_token, id_token, session) are refused at load: they must never reach an external origin.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-browserCache"&gt;&lt;/a&gt; &lt;code&gt;browserCache&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream-browserCache"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP-cache orientation to the BROWSER for assets the origin serves with no Cache-Control (and no Last-Modified either: without these two headers the browser has no heuristic cache — every re-view re-fetches or revalidates each asset, one full round-trip each). Only 200 responses of content-type image/*, Cache-Control absent only: the origin’s own declarations pass untouched. Sent as &amp;#34;private, max-age=…&amp;#34; — private: resources under authentication stay out of any shared cache; the origin’s ETag remains for revalidation after expiry. Default: absent (headers preserved as-is).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-tokenBroker"&gt;&lt;/a&gt; &lt;code&gt;tokenBroker&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-upstream-tokenBroker"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Per-user credentials supplied by the token broker for the authenticated caller. Requires the top-level tokenBroker block and route.auth (the broker needs an authenticated user id). A missing connection produces a 401/403/409 with a connect_url (403 when the user paused the delegation, 409 when reauthorization is required), or a redirect for frontend routes, never a request without credentials. The same policy applies to REST tool calls produced by an MCP route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-upstream-responseHeaders"&gt;routes.upstream.responseHeaders&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Adjustment of the backend’s RESPONSE headers before sending to the browser — typically remove an origin Content-Security-Policy that would block the injected guard script, or set a deployment header. Prefer csp.merge (hashes) or csp.own (explicit removal, logged) for CSP: removing the origin’s CSP here is a blunt, unlogged operation and loses the origin’s protections.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-responseHeaders-set"&gt;&lt;/a&gt; &lt;code&gt;set&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Headers added/overwritten on the response; values with ${VAR} interpolation (container environment); empty value = header removed (never transmitted empty).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-responseHeaders-remove"&gt;&lt;/a&gt; &lt;code&gt;remove&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Header names removed from the response (e.g. Content-Security-Policy).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-upstream-rewriteBody"&gt;routes.upstream.rewriteBody&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Rewriting of the HTML body (200 text/html only, STREAMING — O(1) memory): the origin’s absolute URLs cited in the pages (&amp;#34;https://origin/…&amp;#34;, &amp;#34;http://origin/…&amp;#34;, &amp;#34;//origin/…&amp;#34;) are rewritten to the route’s public host, so the browser stays in the proxy. Any explicit port is part of the rewritten prefix and is lost (target served on the standard port). The path, query and fragment follow as-is. Routes expanded from one wildcard automatically rewrite sibling editions toward their public hosts. &lt;code&gt;targets&lt;/code&gt; and &lt;code&gt;followRoutes&lt;/code&gt; add explicit cross-route mappings (bare hosts only: the request’s scheme and port are inherited). At runtime (fetch/XHR/sendBeacon launched by the site), the client SW served on /__gate-one_pwa/sw.js applies the same policy — it is auto-registered by the guard script, served pre-authentication. One same policy (origins × exceptions × targets) is implemented three times (Go engine, client SW, script patch) — parity tested. Default: absent (no body rewriting).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteBody-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;true = engine active (the block is present to stay declarative; absent = disabled).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteBody-except"&gt;&lt;/a&gt; &lt;code&gt;except&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string or object&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exceptions by path prefix: string entry (&amp;#34;/reading/…&amp;#34;) = these URLs stay at the ORIGIN (out-of-proxy reading link); object entry {path, to} = rewritten to an ALTERNATIVE public base. Longest prefix wins. &amp;#39;/…&amp;#39; prefix mandatory, &amp;#39;?&amp;#39;/&amp;#39;#&amp;#39; forbidden, 256 bytes max; &amp;#39;to&amp;#39; = absolute http(s) URL, trailing slashes trimmed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteBody-targets"&gt;&lt;/a&gt; &lt;code&gt;targets&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Explicit cross-route mappings: backend origin host → public route host. Bare hosts only (no scheme, port, path or wildcard); the key must be an origin of a declared route and the value the public host of a declared route. The request’s scheme and port are inherited. Automatic wildcard siblings are added before these entries; a conflicting mapping is refused at load.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteBody-followRoutes"&gt;&lt;/a&gt; &lt;code&gt;followRoutes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Selectors over declared routes BY PUBLIC HOST (exact host or &amp;#39;&lt;strong&gt;.suffix&amp;#39;; a bare &amp;#39;&lt;/strong&gt;&amp;#39; is refused). Each selected route’s backend origins are rewritten to its public host. Resolved after wildcard expansion; an unmatched selector, a self-only match or an ambiguous origin is refused at load.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-upstream-rewriteCookies"&gt;routes.upstream.rewriteCookies&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Translation of the Set-Cookie set by the origin: a Domain attribute targeting its own namespace (&amp;#34;Domain=original…domain.dev&amp;#34;) would be rejected by the browser from the public host — the cookie would be silently lost. Active: a Domain targeting the origin host (equal or parent) is rewritten to the public host in &amp;#34;rewrite&amp;#34; mode (the sharing scope — host + subdomains — is transposed as-is), or the attribute is removed in &amp;#34;strip&amp;#34; mode (host-only on the public host). Other cookies pass intact (surgery of the Domain attribute only: Path/Secure/HttpOnly/SameSite/Expires come out byte-exact). Auth protection: an origin Set-Cookie bearing a name reserved for the gateway session (access_token, refresh_token, id_token, session) is removed with a warning — set on the same public host, it would overwrite the session cookies. Default: absent (no cookie rewriting).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-rewriteCookies-domain"&gt;&lt;/a&gt; &lt;code&gt;domain&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;rewrite&lt;/code&gt;, &lt;code&gt;strip&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&amp;#34;rewrite&amp;#34; (recommended) = Domain transposed to the public host; &amp;#34;strip&amp;#34; = Domain attribute removed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-upstream-browserCache"&gt;routes.upstream.browserCache&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;HTTP-cache orientation to the BROWSER for assets the origin serves with no Cache-Control (and no Last-Modified either: without these two headers the browser has no heuristic cache — every re-view re-fetches or revalidates each asset, one full round-trip each). Only 200 responses of content-type image/*, Cache-Control absent only: the origin’s own declarations pass untouched. Sent as &amp;#34;private, max-age=…&amp;#34; — private: resources under authentication stay out of any shared cache; the origin’s ETag remains for revalidation after expiry. Default: absent (headers preserved as-is).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-browserCache-imagesMaxAgeSeconds"&gt;&lt;/a&gt; &lt;code&gt;imagesMaxAgeSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Freshness duration (seconds) granted to the images (content-type image/*). E.g. 604800 = a week; 31536000 = a year (only if these files are immutable: the image names followed here are the capture timestamps, not content hashes — prefer a moderate duration if the app can re-edite a photo). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-upstream-tokenBroker"&gt;routes.upstream.tokenBroker&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Per-user credentials supplied by the token broker for the authenticated caller. Requires the top-level tokenBroker block and route.auth (the broker needs an authenticated user id). A missing connection produces a 401/403/409 with a connect_url (403 when the user paused the delegation, 409 when reauthorization is required), or a redirect for frontend routes, never a request without credentials. The same policy applies to REST tool calls produced by an MCP route.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-tokenBroker-provider"&gt;&lt;/a&gt; &lt;code&gt;provider&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Broker provider name (e.g. github). Validated against GET /providers at startup; Gate One never stores the provider’s client secret. Pattern: &lt;code&gt;^[a-z0-9][a-z0-9_-]{0,63}$&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-tokenBroker-header"&gt;&lt;/a&gt; &lt;code&gt;header&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Backend request header receiving the access token. Default Authorization. Host, Cookie, X-User-&lt;strong&gt;, X-Forwarded-&lt;/strong&gt; and X-Gate-One-* names are refused.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-upstream-tokenBroker-prefix"&gt;&lt;/a&gt; &lt;code&gt;prefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Value prepended to the access token. Default &amp;#34;Bearer &amp;#34;. An explicit empty string sends the raw token.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-auth"&gt;routes.auth&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Authentication policy. Empty ({}) = authentication ALWAYS required. auth.when holds TECHNICAL conditions (method/query/header/body) deciding when authentication is required: one object (AND of its conditions) or an array (OR of ANDs — required if ANY element matches); absent/empty = always required. auth.identity holds IDENTITY conditions (roles/scopes/claims/user), checked after successful authentication (403 otherwise) and only on requests that were actually authenticated.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-provider"&gt;&lt;/a&gt; &lt;code&gt;provider&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;ID of the authProviders entry used to verify this route. Empty = defaultAuthProvider. The binding is static and compiled at load; a request cannot choose another provider.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-when"&gt;&lt;/a&gt; &lt;code&gt;when&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;object or array of object&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Technical conditions deciding WHEN authentication is required. Empty = always. One object = AND; an array = OR of ANDs.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-identity"&gt;&lt;/a&gt; &lt;code&gt;identity&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-auth-identity"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Identity policy conditions, evaluated AFTER authentication on the verified token (failure = 403 forbidden). All conditions combine with AND.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-auth-identity"&gt;routes.auth.identity&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Identity policy conditions, evaluated AFTER authentication on the verified token (failure = 403 forbidden). All conditions combine with AND.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-identity-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required Keycloak roles (realm roles + flattened client roles, see auth-bridge’s X-Roles). AND between them. Example of a fixed name: offline_access (realm role granted to every user via default-roles-&amp;lt;realm&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-identity-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required granted scopes (token &lt;code&gt;scope&lt;/code&gt; claim, see auth-bridge’s X-Scopes). AND between them. Example of a fixed name: profile (default client scope, always present).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-identity-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Token claims: key = claim name, value = one accepted string or a list of accepted strings (OR / anyOf on the same claim). &amp;#34;*&amp;#34; = the claim is present. All keys combine with AND. A token claim that is itself a list (groups, roles…) matches when one of its elements matches. Example: {&amp;#34;email&amp;#34;: [&amp;#34;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&amp;#34;, &amp;#34;&lt;a href="mailto:a.rolland@example.com"&gt;a.rolland@example.com&lt;/a&gt;&amp;#34;], &amp;#34;email_verified&amp;#34;: &amp;#34;true&amp;#34;}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-auth-identity-user"&gt;&lt;/a&gt; &lt;code&gt;user&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact username required (preferred_username).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-rateLimit"&gt;routes.rateLimit&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Rate limiting: fixed window per identity (authenticated user, else real IP via X-Forwarded-For), per route. Full window = 429 + Retry-After (seconds). Periods: second|minute|hour|day.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-requests"&gt;&lt;/a&gt; &lt;code&gt;requests&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum number of requests in the period.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-period"&gt;&lt;/a&gt; &lt;code&gt;period&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rate-limit period: second, minute, hour or day.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when"&gt;&lt;/a&gt; &lt;code&gt;when&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-rateLimit-when"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rate-limit / quota triggering conditions (rateLimit.when, quota.when). Two families: technical (method/query/header/body — evaluated BEFORE authentication) and identity (roles/scopes/claims/user — evaluated AFTER authentication on the verified token). All conditions combine with AND. NB: the authentication policy (auth) does NOT use this type: auth.when takes technical conditions only, auth.identity takes identity conditions only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-rateLimit-when"&gt;routes.rateLimit.when&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Rate-limit / quota triggering conditions (rateLimit.when, quota.when). Two families: technical (method/query/header/body — evaluated BEFORE authentication) and identity (roles/scopes/claims/user — evaluated AFTER authentication on the verified token). All conditions combine with AND. NB: the authentication policy (auth) does NOT use this type: auth.when takes technical conditions only, auth.identity takes identity conditions only.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-method"&gt;&lt;/a&gt; &lt;code&gt;method&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact HTTP method (e.g. &amp;#34;POST&amp;#34;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-query"&gt;&lt;/a&gt; &lt;code&gt;query&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of URL parameters.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-header"&gt;&lt;/a&gt; &lt;code&gt;header&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of headers. Caution: a header is forgeable by the client — never put an authorization there (use roles instead).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-body"&gt;&lt;/a&gt; &lt;code&gt;body&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to any&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of fields of the parsed JSON body (flattened one level).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required Keycloak roles (realm roles + flattened client roles, see auth-bridge’s X-Roles). AND between them. Example of a fixed name: offline_access (realm role granted to every user via default-roles-&amp;lt;realm&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required granted scopes (token &lt;code&gt;scope&lt;/code&gt; claim, see auth-bridge’s X-Scopes). AND between them. Example of a fixed name: profile (default client scope, always present).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Token claims: key = claim name, value = one accepted string or a list of accepted strings (OR / anyOf on the same claim). &amp;#34;*&amp;#34; = the claim is present. All keys combine with AND. A token claim that is itself a list (groups, roles…) matches when one of its elements matches. Example: {&amp;#34;email&amp;#34;: [&amp;#34;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&amp;#34;, &amp;#34;&lt;a href="mailto:a.rolland@example.com"&gt;a.rolland@example.com&lt;/a&gt;&amp;#34;], &amp;#34;email_verified&amp;#34;: &amp;#34;true&amp;#34;}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-rateLimit-when-user"&gt;&lt;/a&gt; &lt;code&gt;user&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact username required (preferred_username).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-quota"&gt;routes.quota&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Cumulative quota: same mechanics as rateLimit with a longer window in practice (day). Full window = 429 + Retry-After.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-limit"&gt;&lt;/a&gt; &lt;code&gt;limit&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Maximum billable units in the period.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-period"&gt;&lt;/a&gt; &lt;code&gt;period&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Quota period: second, minute, hour or day.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when"&gt;&lt;/a&gt; &lt;code&gt;when&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-quota-when"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rate-limit / quota triggering conditions (rateLimit.when, quota.when). Two families: technical (method/query/header/body — evaluated BEFORE authentication) and identity (roles/scopes/claims/user — evaluated AFTER authentication on the verified token). All conditions combine with AND. NB: the authentication policy (auth) does NOT use this type: auth.when takes technical conditions only, auth.identity takes identity conditions only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-quota-when"&gt;routes.quota.when&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Rate-limit / quota triggering conditions (rateLimit.when, quota.when). Two families: technical (method/query/header/body — evaluated BEFORE authentication) and identity (roles/scopes/claims/user — evaluated AFTER authentication on the verified token). All conditions combine with AND. NB: the authentication policy (auth) does NOT use this type: auth.when takes technical conditions only, auth.identity takes identity conditions only.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-method"&gt;&lt;/a&gt; &lt;code&gt;method&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact HTTP method (e.g. &amp;#34;POST&amp;#34;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-query"&gt;&lt;/a&gt; &lt;code&gt;query&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of URL parameters.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-header"&gt;&lt;/a&gt; &lt;code&gt;header&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of headers. Caution: a header is forgeable by the client — never put an authorization there (use roles instead).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-body"&gt;&lt;/a&gt; &lt;code&gt;body&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to any&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact equality of fields of the parsed JSON body (flattened one level).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required Keycloak roles (realm roles + flattened client roles, see auth-bridge’s X-Roles). AND between them. Example of a fixed name: offline_access (realm role granted to every user via default-roles-&amp;lt;realm&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Required granted scopes (token &lt;code&gt;scope&lt;/code&gt; claim, see auth-bridge’s X-Scopes). AND between them. Example of a fixed name: profile (default client scope, always present).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Token claims: key = claim name, value = one accepted string or a list of accepted strings (OR / anyOf on the same claim). &amp;#34;*&amp;#34; = the claim is present. All keys combine with AND. A token claim that is itself a list (groups, roles…) matches when one of its elements matches. Example: {&amp;#34;email&amp;#34;: [&amp;#34;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&amp;#34;, &amp;#34;&lt;a href="mailto:a.rolland@example.com"&gt;a.rolland@example.com&lt;/a&gt;&amp;#34;], &amp;#34;email_verified&amp;#34;: &amp;#34;true&amp;#34;}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-quota-when-user"&gt;&lt;/a&gt; &lt;code&gt;user&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Exact username required (preferred_username).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-openapi"&gt;routes.openapi&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;OpenAPI document used to derive REST operations and MCP tools for this route.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-openapi-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OpenAPI 3.x JSON document of the host (absolute URL, or path relative to the route backend). Also the document used to resolve the mcp policy’s operations.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-openapi-public"&gt;&lt;/a&gt; &lt;code&gt;public&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;false = the openapi.json is only served authenticated.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-mcp"&gt;routes.mcp&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Expose a route as an MCP service: protected-resource identifier, scope, tools and metadata.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Enable the MCP service on this route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default: /mcp.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Service name, referenced by mcpSets members. Empty = the route cannot be a set member.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-standalone"&gt;&lt;/a&gt; &lt;code&gt;standalone&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Expose this service on its own endpoint (default true). false = served only through the mcpSets referencing it (the set carries the access rights).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-resource"&gt;&lt;/a&gt; &lt;code&gt;resource&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OAuth protected-resource identifier (audience) of the standalone service. Empty = the endpoint URL. Ignored when the service is reached through a set.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-scope"&gt;&lt;/a&gt; &lt;code&gt;scope&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Keycloak client scope required from MCP clients (bearer &lt;code&gt;scope&lt;/code&gt; claim), announced in /.well-known/oauth-protected-resource and checked by auth-bridge (internal X-MCP-Scope header). The realm must grant it. Default: mcp-tools.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-operations"&gt;&lt;/a&gt; &lt;code&gt;operations&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-routes-mcp-operations"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;REST operations exposed as MCP tools. Empty = no tool (the MCP endpoint still serves metadata and initialization). Mutually exclusive with upstream.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-upstream"&gt;&lt;/a&gt; &lt;code&gt;upstream&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-mcp-upstream"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Proxy an external MCP server over Streamable HTTP instead of deriving local REST tools. The upstream receives the per-user token of upstream.tokenBroker (or static upstream.headers), never the Gate One bearer. Tool filtering is enforced on both tools/list and tools/call.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-mcp-operations"&gt;routes.mcp.operations&lt;/h5&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-operations-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Tool name exposed to MCP clients (unique per route).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-operations-operationId"&gt;&lt;/a&gt; &lt;code&gt;operationId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;operationId resolved in the host’s OpenAPI document; the tool method, path, parameters and body schema are derived from it. An unresolved operationId refuses the configuration load.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-mcp-upstream"&gt;routes.mcp.upstream&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Proxy an external MCP server over Streamable HTTP instead of deriving local REST tools. The upstream receives the per-user token of upstream.tokenBroker (or static upstream.headers), never the Gate One bearer. Tool filtering is enforced on both tools/list and tools/call.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-upstream-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Full upstream Streamable HTTP endpoint. Default: the route backend. The incoming /mcp path is not appended automatically.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-upstream-tools"&gt;&lt;/a&gt; &lt;code&gt;tools&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-mcp-upstream-tools"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Glob patterns (path.Match syntax) over MCP tool names. Include non-empty = only matching tools are exposed; Exclude always wins. Hidden tools are also refused on tools/call.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect5"&gt;&#10;&lt;h6 id="config-routes-mcp-upstream-tools"&gt;routes.mcp.upstream.tools&lt;/h6&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Glob patterns (path.Match syntax) over MCP tool names. Include non-empty = only matching tools are exposed; Exclude always wins. Hidden tools are also refused on tools/call.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-upstream-tools-include"&gt;&lt;/a&gt; &lt;code&gt;include&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allow-list patterns (e.g. &amp;#34;list_*&amp;#34;, &amp;#34;get_*&amp;#34;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-mcp-upstream-tools-exclude"&gt;&lt;/a&gt; &lt;code&gt;exclude&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Deny-list patterns (e.g. &amp;#34;delete_*&amp;#34;, &amp;#34;*_secret&amp;#34;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-pwa"&gt;routes.pwa&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;PWA shell, manifest, icons and service-worker cache policy for a frontend route.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Enable the PWA shell on this route.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Application name shown in the PWA manifest.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-shortName"&gt;&lt;/a&gt; &lt;code&gt;shortName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Short application name for the home screen.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-themeColor"&gt;&lt;/a&gt; &lt;code&gt;themeColor&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Theme color for the PWA manifest and browser UI.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-icon"&gt;&lt;/a&gt; &lt;code&gt;icon&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Legacy singular (still read).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-icons"&gt;&lt;/a&gt; &lt;code&gt;icons&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Same-host paths referenced by the manifest (Chrome: 192×192 and 512×512 PNG for full install).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache"&gt;&lt;/a&gt; &lt;code&gt;apiCache&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-pwa-apiCache"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;One service-worker API cache policy (path prefix, method, retention).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches"&gt;&lt;/a&gt; &lt;code&gt;apiCaches&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-routes-pwa-apiCaches"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;API cache policies for the service worker.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiGETCache"&gt;&lt;/a&gt; &lt;code&gt;apiGETCache&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-pwa-apiGETCache"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Its presence activates the universal GET cache (everything nothing else covers).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-networkOnly"&gt;&lt;/a&gt; &lt;code&gt;networkOnly&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-pwa-networkOnly"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Its presence activates the &amp;#34;never cached&amp;#34; route. When a PWA route shares the authentication scope, the identity-provider endpoints (discovery, authorize, token, JWKS, end-session) and the RP callback carrying a one-time code/state MUST be excluded, or the service worker can replay a stale identity or a one-time code.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-assets"&gt;&lt;/a&gt; &lt;code&gt;assets&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-pwa-assets"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Strategy of same-origin pages/assets (documents, scripts, styles). Default: staleWhileRevalidate without timeout.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-pwa-apiCache"&gt;routes.pwa.apiCache&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One service-worker API cache policy (path prefix, method, retention).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path prefix of the API responses cached by the service worker.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-method"&gt;&lt;/a&gt; &lt;code&gt;method&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;POST (default) = network-first offline replay of POST/SSE; GET = SWR cache of this exact path; none = full opt-out (never cached, excluded from the apiGETCache catch-all).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-maxEntries"&gt;&lt;/a&gt; &lt;code&gt;maxEntries&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 50.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-maxAgeSeconds"&gt;&lt;/a&gt; &lt;code&gt;maxAgeSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 86400 (24 h).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-maxEntrySizeBytes"&gt;&lt;/a&gt; &lt;code&gt;maxEntrySizeBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 2 MiB — beyond, streamed but not cached.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-version"&gt;&lt;/a&gt; &lt;code&gt;version&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Semantic invalidation of the endpoint’s cache (bump it when the backend result changes).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-idleFinalizeMs"&gt;&lt;/a&gt; &lt;code&gt;idleFinalizeMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 1500 — finalizes the cached response after this SSE silence.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-networkTimeoutSeconds"&gt;&lt;/a&gt; &lt;code&gt;networkTimeoutSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 3 — network delay before the cache fallback (headers only).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCache-offlineFastPath"&gt;&lt;/a&gt; &lt;code&gt;offlineFastPath&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default true: offline, serves the cache directly. false = the network failure (bounded by networkTimeoutSeconds) triggers the fallback — for endpoints where replaying a write would be wrong.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-pwa-apiCaches"&gt;routes.pwa.apiCaches&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One service-worker API cache policy (path prefix, method, retention).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path prefix of the API responses cached by the service worker.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-method"&gt;&lt;/a&gt; &lt;code&gt;method&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;none&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;POST (default) = network-first offline replay of POST/SSE; GET = SWR cache of this exact path; none = full opt-out (never cached, excluded from the apiGETCache catch-all).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-maxEntries"&gt;&lt;/a&gt; &lt;code&gt;maxEntries&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 50.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-maxAgeSeconds"&gt;&lt;/a&gt; &lt;code&gt;maxAgeSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 86400 (24 h).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-maxEntrySizeBytes"&gt;&lt;/a&gt; &lt;code&gt;maxEntrySizeBytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 2 MiB — beyond, streamed but not cached.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-version"&gt;&lt;/a&gt; &lt;code&gt;version&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Semantic invalidation of the endpoint’s cache (bump it when the backend result changes).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-idleFinalizeMs"&gt;&lt;/a&gt; &lt;code&gt;idleFinalizeMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 1500 — finalizes the cached response after this SSE silence.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-networkTimeoutSeconds"&gt;&lt;/a&gt; &lt;code&gt;networkTimeoutSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default 3 — network delay before the cache fallback (headers only).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiCaches-offlineFastPath"&gt;&lt;/a&gt; &lt;code&gt;offlineFastPath&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default true: offline, serves the cache directly. false = the network failure (bounded by networkTimeoutSeconds) triggers the fallback — for endpoints where replaying a write would be wrong.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-pwa-apiGETCache"&gt;routes.pwa.apiGETCache&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Its presence activates the universal GET cache (everything nothing else covers).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiGETCache-excludes"&gt;&lt;/a&gt; &lt;code&gt;excludes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Path prefixes never cached by the catch-all.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-apiGETCache-excludePatterns"&gt;&lt;/a&gt; &lt;code&gt;excludePatterns&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;JS regexes (full URL) never cached — invalid syntax rejected at load.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-pwa-networkOnly"&gt;routes.pwa.networkOnly&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Its presence activates the &amp;#34;never cached&amp;#34; route. When a PWA route shares the authentication scope, the identity-provider endpoints (discovery, authorize, token, JWKS, end-session) and the RP callback carrying a one-time code/state MUST be excluded, or the service worker can replay a stale identity or a one-time code.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-networkOnly-excludePatterns"&gt;&lt;/a&gt; &lt;code&gt;excludePatterns&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;JS regexes (full URL) → straight to the network, no cache.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-pwa-assets"&gt;routes.pwa.assets&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Strategy of same-origin pages/assets (documents, scripts, styles). Default: staleWhileRevalidate without timeout.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-assets-strategy"&gt;&lt;/a&gt; &lt;code&gt;strategy&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;staleWhileRevalidate (default) | networkFirst | cacheFirst (case-free, normalized).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-pwa-assets-networkTimeoutSeconds"&gt;&lt;/a&gt; &lt;code&gt;networkTimeoutSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;For networkFirst (default 3).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-csp"&gt;routes.csp&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Content-Security-Policy emitted (or amended) by the gateway — the only component able to generate a per-response nonce and write it into the HTML it already rewrites (guard, PWA, custom injections). By default the origin’s policy is NEVER removed or weakened: the gateway’s policy is added as a SECOND header (browsers enforce all of them, so the effective rule is the strictest) and the hashes of the gateway’s own injected script and guard stylesheet are APPENDED to the origin’s script-src / style-src (script-src-elem &amp;gt; script-src &amp;gt; default-src, style-src-elem &amp;gt; style-src &amp;gt; default-src). Set own=true to remove the origin policy explicitly and let the gateway own it (opt-in, logged, requires mode nonce/hash and reportOnly=false). Applied to HTML responses only.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-mode"&gt;&lt;/a&gt; &lt;code&gt;mode&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;merge&lt;/code&gt;, &lt;code&gt;hash&lt;/code&gt;, &lt;code&gt;nonce&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&amp;#34;off&amp;#34; = nothing (the origin’s policy passes as-is); &amp;#34;merge&amp;#34; = keep the origin policy and only add the hashes of the gateway’s injected scripts (no policy of our own); &amp;#34;hash&amp;#34; = emit our policy with those hashes, no body rewrite; &amp;#34;nonce&amp;#34; = emit our policy with a per-response nonce and stamp the HTML in STREAMING mode (O(1) memory, upstream forced to gzip so the body is plain text).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-reportOnly"&gt;&lt;/a&gt; &lt;code&gt;reportOnly&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Emit Content-Security-Policy-Report-Only instead of the enforcing header (progressive rollout: violations are collected, nothing is blocked). Requires mode nonce or hash.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-own"&gt;&lt;/a&gt; &lt;code&gt;own&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;The gateway OWNS the policy: the origin’s enforced and report-only CSP headers are removed before ours is emitted. Opt-in and logged (never silent). Requires mode nonce or hash and reportOnly=false: removing the origin’s enforcing policy to replace it with a report-only one would remove protection without enforcing anything. Use only for a site you control/accept, with a complete policy.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-reportTo"&gt;&lt;/a&gt; &lt;code&gt;reportTo&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Local path served by the gateway collecting the violations (report-uri). Default: /__gate-one_csp/report. Bounded ring buffer (256 entries), 16 KiB body limit, 50 reports/second, never authenticated. Pattern: &lt;code&gt;&lt;sup&gt;/[&lt;/sup&gt;\s?#]*$&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-stampScripts"&gt;&lt;/a&gt; &lt;code&gt;stampScripts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;inline&lt;/code&gt;, &lt;code&gt;all&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&amp;#34;inline&amp;#34; (default) = only &amp;lt;script&amp;gt; tags WITHOUT src receive the nonce (external scripts stay governed by the host allow-list); &amp;#34;all&amp;#34; = every &amp;lt;script&amp;gt; tag. Nonce mode only. A tag that already carries a nonce is never rewritten.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-csp-directives"&gt;&lt;/a&gt; &lt;code&gt;directives&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Directive name → sources, as one string (&amp;#34;&amp;#39;self&amp;#39; &lt;a "="" class="bare" href="https://x"&gt;https://x&amp;#34;&lt;/a&gt;) or an array. The gateway appends the nonce (nonce mode) and the injected scripts&amp;#39; / guard stylesheet’s hashes to the effective script-src / style-src, and report-uri when reportTo is set. To let the guard’s nonce/hash pass, declare style-src (e.g. &amp;#34;&amp;#39;self&amp;#39;&amp;#34;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-userBadge"&gt;routes.userBadge&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;User badge injected by the guard script once authenticated: collapsed on the top edge (one line = username), expanded on hover/keyboard focus — chosen claims + logout button (OIDC end_session + cookie clearing). Absent = no badge.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-position"&gt;&lt;/a&gt; &lt;code&gt;position&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Top edge (default right).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;What the expanded badge displays as claims: true = every claim of the session, false = none, a list = only these (missing ones omitted).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Session roles displayed as chips in the expanded badge: true = every role, false = none, a list = only these (same data as the auth.identity.roles conditions, served by the /__gate-one/auth probe).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Granted scopes displayed as chips in the expanded badge: true = every scope, false = none, a list = only these.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-logoutLabel"&gt;&lt;/a&gt; &lt;code&gt;logoutLabel&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Label of the logout button (default Log out).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-links"&gt;&lt;/a&gt; &lt;code&gt;links&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-routes-userBadge-links"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Application-specific links, appended after the connector links (account, then services when the deployment delegates). Duplicate URLs are dropped (the connector link wins); at most 8 links after merge.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-loginBadge"&gt;&lt;/a&gt; &lt;code&gt;loginBadge&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;true = the badge ALSO appears when anonymous, from the very first visit, in invitation mode (&amp;#34;👤 Sign in&amp;#34;) — clicked, it opens the login tab: offer sign-in without touching the site’s markup. Default false (badge only once authenticated; when anonymous it only appears after a detected session death).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-userBadge-links"&gt;routes.userBadge.links&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-links-label"&gt;&lt;/a&gt; &lt;code&gt;label&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Displayed text. Optional for the connector links (default Account/Services); required for userBadge.links. Maximum length: 64.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-links-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;http(s) absolute URL or local absolute path (/…​). Maximum length: 2048.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-userBadge-links-target"&gt;&lt;/a&gt; &lt;code&gt;target&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;_blank&lt;/code&gt;, &lt;code&gt;_self&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Link target. Default _blank.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-uiGate"&gt;routes.uiGate&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;UI gating rule by config — for fronts whose markup cannot be modified (if you control the HTML, prefer the data-gtw-* attributes). The selected element is visible only if the session satisfies the conditions (OR on roles, OR on scopes, AND on claims). PRECEDENCE: an element carrying at least one data-gtw-* attribute ignores uiGate rules; several rules on a same element combine with AND; invalid selector = rule ignored.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-selector"&gt;&lt;/a&gt; &lt;code&gt;selector&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;CSS selector (querySelectorAll) of the targeted elements.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Visible if AT LEAST ONE of these roles is held.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Visible if AT LEAST ONE of these scopes is granted.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string or array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;All keys must match; each value is one accepted string or a list (OR / anyOf); &amp;#34;*&amp;#34; = presence. A token claim that is itself a list matches when one element matches. Example: {&amp;#34;email&amp;#34;: [&amp;#34;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&amp;#34;, &amp;#34;&lt;a href="mailto:a.rolland@example.com"&gt;a.rolland@example.com&lt;/a&gt;&amp;#34;]}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-auth"&gt;&lt;/a&gt; &lt;code&gt;auth&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;after&lt;/code&gt;, &lt;code&gt;before&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Turns the selected elements into login triggers: after = native action preserved + invitation tab; before = click neutralized + direct tab. Activation only: deactivations (unchecking, closing details, reset, returning a value control to its OFF value) are never gated. Value controls (select/range/date/…) are gated on change, with their default value as the OFF value (data-gtw-auth-off on the element overrides it).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-uiGate-hidden"&gt;&lt;/a&gt; &lt;code&gt;hidden&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;before&lt;/code&gt;, &lt;code&gt;after&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Hiding: before = hidden before authentication (any click reaching it is neutralized → banner); after = hidden once authenticated.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-routes-authGuard"&gt;routes.authGuard&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;401 guard script (login without reloading: tab + replay + banner + declarative gating). Active by default on frontend routes; no-op elsewhere. The guard intercepts the 401 (login) and, when authGuard.forbidden.banner is set, the gateway’s OWN identity 403; a 403 coming from the backend is never concerned.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-enabled"&gt;&lt;/a&gt; &lt;code&gt;enabled&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;false = opt-out (the front handles its own 401).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-loginUrl"&gt;&lt;/a&gt; &lt;code&gt;loginUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default: &lt;a class="bare" href="https://login.cladone.com/login"&gt;https://login.cladone.com/login&lt;/a&gt; (auth-bridge page).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-forbidden"&gt;&lt;/a&gt; &lt;code&gt;forbidden&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-routes-authGuard-forbidden"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Opt-in UX for the gateway’s OWN identity 403 (rights refusal — auth.identity not satisfied). A backend 403 is never concerned. Browser navigations get a readable HTML page (or a redirect to pageUrl); fetch()/XHR get the JSON 403 unchanged, plus an optional dismissable banner hinting the front authors to hide the feature.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-routes-authGuard-forbidden"&gt;routes.authGuard.forbidden&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Opt-in UX for the gateway’s OWN identity 403 (rights refusal — auth.identity not satisfied). A backend 403 is never concerned. Browser navigations get a readable HTML page (or a redirect to pageUrl); fetch()/XHR get the JSON 403 unchanged, plus an optional dismissable banner hinting the front authors to hide the feature.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-forbidden-banner"&gt;&lt;/a&gt; &lt;code&gt;banner&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;true = the injected guard script shows a dismissable banner when a fetch() sees the gateway’s identity 403. Default false.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-forbidden-pageUrl"&gt;&lt;/a&gt; &lt;code&gt;pageUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Browser navigations refused on identity are redirected there (302) instead of the built-in HTML page.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-routes-authGuard-forbidden-message"&gt;&lt;/a&gt; &lt;code&gt;message&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Overrides the built-in forbidden page’s message text.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-ssoGroups"&gt;ssoGroups&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One cross-domain SSO group. Every provider in the group shares issuer, client, scopes, session key and session store; only login host, cookie domain and domain-specific links may differ.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-id"&gt;&lt;/a&gt; &lt;code&gt;id&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Group identifier used in diagnostics and -check output. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;oidc&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Provider type. Only oidc is allowed in a group; JWT providers stay standalone authProviders entries. Default: oidc.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-issuer"&gt;&lt;/a&gt; &lt;code&gt;issuer&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC issuer shared by every provider in the group.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-clientId"&gt;&lt;/a&gt; &lt;code&gt;clientId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC client id shared by every provider. Register every provider callback URL at the IdP. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-clientSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clientSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the shared OIDC client secret. Empty = public client (PKCE only).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC scopes requested for every provider.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-roleClaims"&gt;&lt;/a&gt; &lt;code&gt;roleClaims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dot paths in the ID token whose values become roles, shared by every provider.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-scopesClaim"&gt;&lt;/a&gt; &lt;code&gt;scopesClaim&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Claim holding granted scopes. Default: scope; scp is always also read.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionKeyEnv"&gt;&lt;/a&gt; &lt;code&gt;sessionKeyEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the RP cookie signing key. Required with Redis; identical for every provider in the group.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore"&gt;&lt;/a&gt; &lt;code&gt;sessionStore&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-ssoGroups-sessionStore"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;RP-side revocation store (back-channel logout, RP logout). Default: bbolt at ./gate-one-state.db, relative to the config file. bbolt is single-writer: a second Gate One instance on the same file is refused. Redis is the shared, multi-instance backend and makes revocation visible on the next request on every instance.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;sessionTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC RP session lifetime. Default 3600 (1h): a short TTL bounds revocation when no shared store is used. The refresh/reauth flow renews it. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-backchannelLogout"&gt;&lt;/a&gt; &lt;code&gt;backchannelLogout&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;OIDC Back-Channel Logout. Absent = auto: enabled when the IdP discovery advertises backchannel_logout_supported. false disables it. Register &amp;lt;loginBaseUrl&amp;gt;/backchannel-logout at the IdP.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-backchannelForwardUrl"&gt;&lt;/a&gt; &lt;code&gt;backchannelForwardUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Migration bridge: after a valid local back-channel revocation, POST the same logout_token to this auth-bridge /backchannel-logout URL so its persistent sid list stays in sync for /auth and /connections. Best effort.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-revocationTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;revocationTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Retention of revocation entries. Default: the issuer’s advertised refresh-token TTL (cladone_refresh_token_ttl_seconds, e.g. the embedded IAM), else 30 days; never shorter than the session TTL. Must cover the refresh-token lifetime for a global logout. A revocation covers only sessions/tokens issued before it, so a later sign-in is accepted (a user is never locked out by their own logout). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-legacyTokenCookies"&gt;&lt;/a&gt; &lt;code&gt;legacyTokenCookies&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Migration bridge: also set auth-bridge’s access_token/refresh_token/id_token cookies on cookieDomain, so auth-bridge’s token-broker proxy routes (/connections, /connect, /oauth) resolve the same session when both share the login host. Default false. The native session cookie remains authoritative for Gate One.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers"&gt;&lt;/a&gt; &lt;code&gt;providers&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-ssoGroups-providers"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;One entry per application domain/provider. Only fields that vary per domain are allowed here.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-ssoGroups-sessionStore"&gt;ssoGroups.sessionStore&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;RP-side revocation store (back-channel logout, RP logout). Default: bbolt at ./gate-one-state.db, relative to the config file. bbolt is single-writer: a second Gate One instance on the same file is refused. Redis is the shared, multi-instance backend and makes revocation visible on the next request on every instance.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;bolt&lt;/code&gt;, &lt;code&gt;redis&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;bolt (default, single instance) or redis (shared, multi-instance, immediate revocation).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-path"&gt;&lt;/a&gt; &lt;code&gt;path&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;bbolt file path. Default ./gate-one-state.db (relative to the config file).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis URL for type redis (redis:// or rediss://). Mutually exclusive with sentinel mode.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-sentinelAddrs"&gt;&lt;/a&gt; &lt;code&gt;sentinelAddrs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis Sentinel addresses (host:port). Required with masterName.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-masterName"&gt;&lt;/a&gt; &lt;code&gt;masterName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis Sentinel master name. Requires sentinelAddrs.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-sentinelUsername"&gt;&lt;/a&gt; &lt;code&gt;sentinelUsername&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;ACL user used to authenticate to the Sentinels themselves (sentinel mode only). Separate from username, which is the Redis data user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-sentinelPasswordEnv"&gt;&lt;/a&gt; &lt;code&gt;sentinelPasswordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Sentinel password (sentinel mode only). Never put the password in this file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-tls"&gt;&lt;/a&gt; &lt;code&gt;tls&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Use TLS in sentinel mode (Sentinels and the discovered master). In URL mode use a rediss:// URL instead.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-tlsCaFile"&gt;&lt;/a&gt; &lt;code&gt;tlsCaFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;PEM CA bundle for the Sentinel TLS connections. Requires tls=true; empty = system roots.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-tlsServerName"&gt;&lt;/a&gt; &lt;code&gt;tlsServerName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;TLS server name override (useful when the Sentinels are addressed by IP). Requires tls=true.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis ACL username.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-passwordEnv"&gt;&lt;/a&gt; &lt;code&gt;passwordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Redis password. Never put the password in this file.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-db"&gt;&lt;/a&gt; &lt;code&gt;db&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis logical database. Default 0. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-prefix"&gt;&lt;/a&gt; &lt;code&gt;prefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Shared revocation key prefix. Default cladone:auth:v1:. Must match the embedded IAM’s redis.authPrefix.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-dialTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;dialTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis dial timeout in milliseconds. Default 500. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-readTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;readTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis read timeout in milliseconds. Default 300. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-writeTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;writeTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis write timeout in milliseconds. Default 300. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-sessionStore-poolSize"&gt;&lt;/a&gt; &lt;code&gt;poolSize&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis connection pool size. Default 64. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-ssoGroups-providers"&gt;ssoGroups.providers&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One domain/provider inside an SSO group. Shared fields (issuer, clientId, sessionStore, …) are deliberately absent: put them on the group.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-id"&gt;&lt;/a&gt; &lt;code&gt;id&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Provider id used by routes (auth.provider). Must be globally unique. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-loginBaseUrl"&gt;&lt;/a&gt; &lt;code&gt;loginBaseUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Public origin of this domain’s login service. Must be the cookieDomain or one of its subdomains.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-loginUrl"&gt;&lt;/a&gt; &lt;code&gt;loginUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional full login page URL. Defaults to loginBaseUrl + /login.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-cookieDomain"&gt;&lt;/a&gt; &lt;code&gt;cookieDomain&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Registrable parent domain for this provider’s session cookie (e.g. app-a.com or app-b.fr). Distinct and non-overlapping within the group; route hosts must be covered by it. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-cookieName"&gt;&lt;/a&gt; &lt;code&gt;cookieName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional session cookie name. Empty = provider-scoped default.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-redirectUrl"&gt;&lt;/a&gt; &lt;code&gt;redirectUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Optional OIDC callback URL. Defaults to loginBaseUrl + /auth/callback. Must be on cookieDomain or a subdomain.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-links"&gt;&lt;/a&gt; &lt;code&gt;links&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-ssoGroups-providers-links"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Links owned by the authentication connector, displayed in the user badge. account is the IdP’s own account console: NO OIDC standard, so the URL is explicit (Keycloak /realms/&amp;lt;realm&amp;gt;/account/, Entra myaccount.microsoft.com, Google myaccount.google.com, Okta /enduser/settings…).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-mcpAudience"&gt;&lt;/a&gt; &lt;code&gt;mcpAudience&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;MCP access-token audience policy. Empty = scope-only (compatible default). A literal value requires that value in aud. &amp;#34;auto&amp;#34; requires the endpoint’s own protected-resource identifier (recommended, and used with Keycloak audience mappers).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-defaultAppUrl"&gt;&lt;/a&gt; &lt;code&gt;defaultAppUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Application to send a bare visit to this provider’s login host root to. Must be a route host of this provider (or a host covered by its cookieDomain). Overrides the group/global fallback for this domain. Prefer a neutral page rather than one application.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-ssoGroups-providers-links"&gt;ssoGroups.providers.links&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Links owned by the authentication connector, displayed in the user badge. account is the IdP’s own account console: NO OIDC standard, so the URL is explicit (Keycloak /realms/&amp;lt;realm&amp;gt;/account/, Entra myaccount.microsoft.com, Google myaccount.google.com, Okta /enduser/settings…).&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-links-account"&gt;&lt;/a&gt; &lt;code&gt;account&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-ssoGroups-providers-links-account"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect5"&gt;&#10;&lt;h6 id="config-ssoGroups-providers-links-account"&gt;ssoGroups.providers.links.account&lt;/h6&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;A link rendered in the expanded user badge. URL: http(s) absolute or a local absolute path (/…​); javascript:/data: are refused. target defaults to _blank; rel is forced to noopener noreferrer.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-links-account-label"&gt;&lt;/a&gt; &lt;code&gt;label&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Displayed text. Optional for the connector links (default Account/Services); required for userBadge.links. Maximum length: 64.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-links-account-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;http(s) absolute URL or local absolute path (/…​). Maximum length: 2048.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ssoGroups-providers-links-account-target"&gt;&lt;/a&gt; &lt;code&gt;target&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;_blank&lt;/code&gt;, &lt;code&gt;_self&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Link target. Default _blank.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Embedded IAM configuration</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/embedded-iam/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/embedded-iam/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/embedded-iam.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The optional &lt;code&gt;cladone-auth&lt;/code&gt; embedded IAM configuration. Secrets are read from the environment; a &lt;code&gt;*Env&lt;/code&gt; field names the variable.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect1"&gt;&#10;&lt;h2 id="config-root"&gt;Fields&lt;/h2&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publicUrl"&gt;&lt;/a&gt; &lt;code&gt;publicUrl&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;External origin of the IAM, without a trailing slash (for example &lt;a class="bare" href="https://auth.example.com"&gt;https://auth.example.com&lt;/a&gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-listen"&gt;&lt;/a&gt; &lt;code&gt;listen&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Default listen address for cmd/cladone-auth (for example :8081).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-sessionCookieName"&gt;&lt;/a&gt; &lt;code&gt;sessionCookieName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IAM SSO cookie shared by all applications in one browser. Default cladone_iam_sid.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants"&gt;&lt;/a&gt; &lt;code&gt;tenants&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Isolated issuers. Each tenant has its own key, client, upstream identity providers and policy.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis"&gt;&lt;/a&gt; &lt;code&gt;redis&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-redis"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Shared store for flows, codes, refresh tokens and the revocation keyspace read by Gate One. Absent = in-memory store, single instance and tests only.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp"&gt;&lt;/a&gt; &lt;code&gt;smtp&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-smtp"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Outbound mail relay for local-account verification emails.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-tenants"&gt;tenants&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-id"&gt;&lt;/a&gt; &lt;code&gt;id&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Tenant identifier; also the /t/{tenant} path segment and default audience. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-clientId"&gt;&lt;/a&gt; &lt;code&gt;clientId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Gate One OIDC client id registered with this tenant. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-clientSecret"&gt;&lt;/a&gt; &lt;code&gt;clientSecret&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Inline client secret. Prefer clientSecretEnv so the secret never lands in the file. Write-only; prefer the &lt;code&gt;*Env&lt;/code&gt; form.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-clientSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clientSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Gate One client secret.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-redirectUris"&gt;&lt;/a&gt; &lt;code&gt;redirectUris&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed Gate One callback URLs (https, or localhost for tests).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-postLogoutRedirectUris"&gt;&lt;/a&gt; &lt;code&gt;postLogoutRedirectUris&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed post-logout targets. List every application origin as &lt;a class="bare" href="https://app.example.com/*"&gt;https://app.example.com/*&lt;/a&gt; (the host Gate One sends as post_logout_redirect_uri). Empty falls back to redirectUris, which covers only the login host, so a logout from an application host would be refused.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-audiences"&gt;&lt;/a&gt; &lt;code&gt;audiences&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Audiences allowed for access tokens. Empty = the tenant id.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google"&gt;&lt;/a&gt; &lt;code&gt;google&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-tenants-google"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream OIDC identity provider configuration. The google key defaults to the Google issuer; other keys require issuer, clientId/Env and clientSecret/Env.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams"&gt;&lt;/a&gt; &lt;code&gt;upstreams&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of &lt;a href="#config-tenants-upstreams"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Named OIDC upstreams (google, microsoft, …). The key is the idp authorize parameter and the chooser label.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-keyFile"&gt;&lt;/a&gt; &lt;code&gt;keyFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Active Ed25519 private key file (base64 raw seed). Empty = ephemeral key, tests/dev only. Mutually exclusive with keyFiles.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-keyFiles"&gt;&lt;/a&gt; &lt;code&gt;keyFiles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Published keys, oldest first, newest active. Used to rotate tokens without invalidating old ones.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-defaultRoles"&gt;&lt;/a&gt; &lt;code&gt;defaultRoles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Roles granted to every authenticated user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-allowedDomains"&gt;&lt;/a&gt; &lt;code&gt;allowedDomains&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed upstream hosted/email domains. Empty = no restriction.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-adminEmails"&gt;&lt;/a&gt; &lt;code&gt;adminEmails&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Email addresses granted the admin role.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-groupRoles"&gt;&lt;/a&gt; &lt;code&gt;groupRoles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Map an upstream group/claim value to IAM roles.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-accessTokenTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;accessTokenTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Access token lifetime in seconds. Default 600. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-idTokenTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;idTokenTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;ID token lifetime in seconds. Default 600. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-refreshTokenTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;refreshTokenTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Refresh token lifetime in seconds. Default 2592000 (30 days). Gate One reads it from discovery to size revocation. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-sessionTtlSeconds"&gt;&lt;/a&gt; &lt;code&gt;sessionTtlSeconds&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IAM SSO session lifetime in seconds. Default 43200 (12 hours). Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-localAccounts"&gt;&lt;/a&gt; &lt;code&gt;localAccounts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Enable the local account lifecycle endpoints (register, verify email) for this tenant. Requires smtp.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-appOrigins"&gt;&lt;/a&gt; &lt;code&gt;appOrigins&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed application origins for a verification continueUrl.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-registrationSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;registrationSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable gating POST /register (server-to-server registration).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings"&gt;&lt;/a&gt; &lt;code&gt;mappings&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants-mappings"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Ordered mapping rules translating upstream claims into IAM roles/scopes/claims. Evaluated on every federated login; results are not persisted on the user. The legacy groupRoles block remains supported for the groups claim.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules"&gt;&lt;/a&gt; &lt;code&gt;rules&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants-rules"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;when/then policy rules: test the incoming token’s claims (when) and grant rights (then), including derived roles (rolesFrom) and copied claims (copyClaims). Evaluated on every login; results are not persisted on the user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-tenants-google"&gt;tenants.google&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Upstream OIDC identity provider configuration. The google key defaults to the Google issuer; other keys require issuer, clientId/Env and clientSecret/Env.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-issuer"&gt;&lt;/a&gt; &lt;code&gt;issuer&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream OIDC issuer. Default &lt;a class="bare" href="https://accounts.google.com"&gt;https://accounts.google.com&lt;/a&gt; for the google upstream; required for other upstreams.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-clientId"&gt;&lt;/a&gt; &lt;code&gt;clientId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream OIDC client id. Prefer clientIdEnv.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-clientIdEnv"&gt;&lt;/a&gt; &lt;code&gt;clientIdEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the upstream client id.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-clientSecret"&gt;&lt;/a&gt; &lt;code&gt;clientSecret&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Inline upstream client secret. Prefer clientSecretEnv. Write-only; prefer the &lt;code&gt;*Env&lt;/code&gt; form.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-clientSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clientSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the upstream client secret.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-prompt"&gt;&lt;/a&gt; &lt;code&gt;prompt&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Forwarded to the upstream authorize endpoint (for example select_account).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-hostedDomain"&gt;&lt;/a&gt; &lt;code&gt;hostedDomain&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Google Workspace hosted domain (hd) restriction.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream scopes. Default openid, profile, email.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-displayName"&gt;&lt;/a&gt; &lt;code&gt;displayName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Label shown on the identity provider chooser. Default: the upstream key.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-google-optional"&gt;&lt;/a&gt; &lt;code&gt;optional&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Skip this upstream when its client id/secret environment variables are empty, instead of refusing startup.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-tenants-upstreams"&gt;tenants.upstreams&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Upstream OIDC identity provider configuration. The google key defaults to the Google issuer; other keys require issuer, clientId/Env and clientSecret/Env.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-issuer"&gt;&lt;/a&gt; &lt;code&gt;issuer&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream OIDC issuer. Default &lt;a class="bare" href="https://accounts.google.com"&gt;https://accounts.google.com&lt;/a&gt; for the google upstream; required for other upstreams.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-clientId"&gt;&lt;/a&gt; &lt;code&gt;clientId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream OIDC client id. Prefer clientIdEnv.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-clientIdEnv"&gt;&lt;/a&gt; &lt;code&gt;clientIdEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the upstream client id.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-clientSecret"&gt;&lt;/a&gt; &lt;code&gt;clientSecret&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Inline upstream client secret. Prefer clientSecretEnv. Write-only; prefer the &lt;code&gt;*Env&lt;/code&gt; form.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-clientSecretEnv"&gt;&lt;/a&gt; &lt;code&gt;clientSecretEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the upstream client secret.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-prompt"&gt;&lt;/a&gt; &lt;code&gt;prompt&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Forwarded to the upstream authorize endpoint (for example select_account).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-hostedDomain"&gt;&lt;/a&gt; &lt;code&gt;hostedDomain&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Google Workspace hosted domain (hd) restriction.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Upstream scopes. Default openid, profile, email.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-displayName"&gt;&lt;/a&gt; &lt;code&gt;displayName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Label shown on the identity provider chooser. Default: the upstream key.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-upstreams-optional"&gt;&lt;/a&gt; &lt;code&gt;optional&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Skip this upstream when its client id/secret environment variables are empty, instead of refusing startup.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-tenants-mappings"&gt;tenants.mappings&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;One claim-to-rights mapping rule.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings-claim"&gt;&lt;/a&gt; &lt;code&gt;claim&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dot path into the upstream token claims, for example groups, realm_access.roles or resource_access.gate-one.roles. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings-values"&gt;&lt;/a&gt; &lt;code&gt;values&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Values to match. If omitted, the rule matches when the claim is present and non-empty.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IAM roles added when the rule matches.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;IAM scopes added when the rule matches.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-mappings-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to any&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Claims copied into issued tokens when the rule matches. Reserved claims (iss, sub, aud, exp, iat, jti, nonce, tenant, roles, scope, sid, email, preferred_username) are refused.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect3"&gt;&#10;&lt;h4 id="config-tenants-rules"&gt;tenants.rules&lt;/h4&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;A when/then policy rule: test the incoming token’s claims and grant rights. Evaluated on every login; results are not persisted on the user.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-when"&gt;&lt;/a&gt; &lt;code&gt;when&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants-rules-when"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Conditions, combined with logical AND. A single condition object is also accepted as shorthand.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then"&gt;&lt;/a&gt; &lt;code&gt;then&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-tenants-rules-then"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Rights granted when every condition matches.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-tenants-rules-when"&gt;tenants.rules.when&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Test one claim of the incoming token.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-when-claim"&gt;&lt;/a&gt; &lt;code&gt;claim&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dot path into the upstream token claims (email, sub, groups, realm_access.roles, …​). Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-when-match"&gt;&lt;/a&gt; &lt;code&gt;match&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;exact&lt;/code&gt;, &lt;code&gt;prefix&lt;/code&gt;, &lt;code&gt;suffix&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt;, &lt;code&gt;glob&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Matching operator. Default exact. prefix/suffix/domain/glob are case-insensitive.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-when-values"&gt;&lt;/a&gt; &lt;code&gt;values&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Values to match. Omitted = the claim must be present and non-empty.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect4"&gt;&#10;&lt;h5 id="config-tenants-rules-then"&gt;tenants.rules.then&lt;/h5&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Rights granted when every condition matches.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-roles"&gt;&lt;/a&gt; &lt;code&gt;roles&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Constant IAM roles.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-scopes"&gt;&lt;/a&gt; &lt;code&gt;scopes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Constant IAM scopes.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-claims"&gt;&lt;/a&gt; &lt;code&gt;claims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to any&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Constant claims copied into issued tokens. Reserved claims are refused.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-rolesFrom"&gt;&lt;/a&gt; &lt;code&gt;rolesFrom&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants-rules-then-rolesFrom"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Derive roles from an incoming claim’s values.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-copyClaims"&gt;&lt;/a&gt; &lt;code&gt;copyClaims&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-tenants-rules-then-copyClaims"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Copy incoming claims into issued tokens, optionally renamed and reshaped.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect5"&gt;&#10;&lt;h6 id="config-tenants-rules-then-rolesFrom"&gt;tenants.rules.then.rolesFrom&lt;/h6&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Turn an incoming claim’s values into IAM roles.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-rolesFrom-claim"&gt;&lt;/a&gt; &lt;code&gt;claim&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dot path into the upstream token claims. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-rolesFrom-transforms"&gt;&lt;/a&gt; &lt;code&gt;transforms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Pipeline applied to each value: lower, upper, prefix:&amp;lt;p&amp;gt;, suffix:&amp;lt;p&amp;gt;, replace:&amp;lt;a&amp;gt;:&amp;lt;b&amp;gt;, keep:&amp;lt;sep&amp;gt;:&amp;lt;from&amp;gt;[:&amp;lt;to&amp;gt;] (keep fields from..to, negative counts from the end, joined by &amp;lt;sep&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect5"&gt;&#10;&lt;h6 id="config-tenants-rules-then-copyClaims"&gt;tenants.rules.then.copyClaims&lt;/h6&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Copy an incoming claim into the issued token.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-copyClaims-from"&gt;&lt;/a&gt; &lt;code&gt;from&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Source claim dot path. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-copyClaims-to"&gt;&lt;/a&gt; &lt;code&gt;to&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Destination claim name. Default: same as from. Reserved names are refused. Minimum length: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenants-rules-then-copyClaims-transforms"&gt;&lt;/a&gt; &lt;code&gt;transforms&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Pipeline applied to each value: lower, upper, prefix:&amp;lt;p&amp;gt;, suffix:&amp;lt;p&amp;gt;, replace:&amp;lt;a&amp;gt;:&amp;lt;b&amp;gt;, keep:&amp;lt;sep&amp;gt;:&amp;lt;from&amp;gt;[:&amp;lt;to&amp;gt;] (keep fields from..to, negative counts from the end, joined by &amp;lt;sep&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-redis"&gt;redis&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Shared store for flows, codes, refresh tokens and the revocation keyspace read by Gate One. Absent = in-memory store, single instance and tests only.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-url"&gt;&lt;/a&gt; &lt;code&gt;url&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis URL (redis:// or rediss://). Mutually exclusive with sentinel mode.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-sentinelAddrs"&gt;&lt;/a&gt; &lt;code&gt;sentinelAddrs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Sentinel addresses (host:port). Required with masterName.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-masterName"&gt;&lt;/a&gt; &lt;code&gt;masterName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis master name for Sentinel discovery.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-sentinelUsername"&gt;&lt;/a&gt; &lt;code&gt;sentinelUsername&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;ACL user for the Sentinel connections (sentinel mode only).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-sentinelPasswordEnv"&gt;&lt;/a&gt; &lt;code&gt;sentinelPasswordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Sentinel password (sentinel mode only).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis ACL user.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-passwordEnv"&gt;&lt;/a&gt; &lt;code&gt;passwordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the Redis password.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-db"&gt;&lt;/a&gt; &lt;code&gt;db&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Redis database number. Default 0. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-prefix"&gt;&lt;/a&gt; &lt;code&gt;prefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Key prefix for IAM state. Default cladone:iam:v1:.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-authPrefix"&gt;&lt;/a&gt; &lt;code&gt;authPrefix&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Key prefix the IAM writes revocations to, read by Gate One. Default cladone:auth:v1:.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-dialTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;dialTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Dial timeout in milliseconds. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-readTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;readTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Read timeout in milliseconds. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-writeTimeoutMs"&gt;&lt;/a&gt; &lt;code&gt;writeTimeoutMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Write timeout in milliseconds. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-poolSize"&gt;&lt;/a&gt; &lt;code&gt;poolSize&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Connection pool size. Minimum: 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-tls"&gt;&lt;/a&gt; &lt;code&gt;tls&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Use TLS for the Sentinel and master/replica connections.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-tlsCaFile"&gt;&lt;/a&gt; &lt;code&gt;tlsCaFile&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;CA bundle for TLS (system roots by default). Requires tls=true.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-redis-tlsServerName"&gt;&lt;/a&gt; &lt;code&gt;tlsServerName&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;TLS server name, useful when Sentinels are addressed by IP. Requires tls=true.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-smtp"&gt;smtp&lt;/h3&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Outbound mail relay for local-account verification emails.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-host"&gt;&lt;/a&gt; &lt;code&gt;host&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;SMTP host.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-port"&gt;&lt;/a&gt; &lt;code&gt;port&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;SMTP port. Default 587 (STARTTLS). Minimum: 1. Maximum: 65535.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-username"&gt;&lt;/a&gt; &lt;code&gt;username&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;SMTP username. Prefer usernameEnv.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-usernameEnv"&gt;&lt;/a&gt; &lt;code&gt;usernameEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the SMTP username.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-passwordEnv"&gt;&lt;/a&gt; &lt;code&gt;passwordEnv&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Environment variable holding the SMTP password.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-smtp-from"&gt;&lt;/a&gt; &lt;code&gt;from&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;From address for verification emails.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Plugin manifest</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/plugin-manifest/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/plugin-manifest/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/plugin-manifest.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The signed manifest shipped with an out-of-process plugin. The operator references it from &lt;code&gt;usage.plugins[].manifest&lt;/code&gt;; the trust store decides whether the signer and the artefact are trusted.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Plugin trust store</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/plugin-trust-store/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/plugin-trust-store/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/plugin-trust-store.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The local allow-list referenced by &lt;code&gt;usage.trustStore&lt;/code&gt;. It is provisioned out-of-band and never fetched from a plugin.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect1"&gt;&#10;&lt;h2 id="config-root"&gt;Fields&lt;/h2&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-keys"&gt;&lt;/a&gt; &lt;code&gt;keys&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Signing keys: key id → raw Ed25519 public key, base64 (standard or raw URL encoding).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-allowedNames"&gt;&lt;/a&gt; &lt;code&gt;allowedNames&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed plugin names. Exact names or glob patterns interpreted with path.Match (for example com.cladone.*).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-allowedDependencies"&gt;&lt;/a&gt; &lt;code&gt;allowedDependencies&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allowed dependency digests: name → sha256 digest.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revokedDigests"&gt;&lt;/a&gt; &lt;code&gt;revokedDigests&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Artefact digests refused even with a valid signature.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-allowAuth"&gt;&lt;/a&gt; &lt;code&gt;allowAuth&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Allow manifests with kind=auth (high-trust modules). Default false.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-coreVersion"&gt;&lt;/a&gt; &lt;code&gt;coreVersion&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Host API version, for example 1.5.0. Compared with the manifest hostAPI constraint.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Publisher feed</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/publisher-feed/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/publisher-feed/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/publisher-feed.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The signed document referenced by &lt;code&gt;publisherFeed.file&lt;/code&gt;: compatible Gate One versions, external components and plugins, with their version-compatibility rules and revocation status.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect1"&gt;&#10;&lt;h2 id="config-root"&gt;Fields&lt;/h2&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-schemaVersion"&gt;&lt;/a&gt; &lt;code&gt;schemaVersion&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer (fixed: &lt;code&gt;1&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Feed schema version. Always 1.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-kind"&gt;&lt;/a&gt; &lt;code&gt;kind&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (fixed: &lt;code&gt;publisher-feed&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Document kind. Always publisher-feed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-publisher"&gt;&lt;/a&gt; &lt;code&gt;publisher&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Publisher identity.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-generatedAt"&gt;&lt;/a&gt; &lt;code&gt;generatedAt&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;RFC 3339 timestamp of generation.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-validUntil"&gt;&lt;/a&gt; &lt;code&gt;validUntil&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;RFC 3339 timestamp after which the feed is stale. In enforce mode a stale feed refuses new plugin loads.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-hosts"&gt;&lt;/a&gt; &lt;code&gt;hosts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-hosts"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Compatible Gate One releases.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-externalComponents"&gt;&lt;/a&gt; &lt;code&gt;externalComponents&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-externalComponents"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Compatible non-Gate-One components (Redis, an IdP, …).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins"&gt;&lt;/a&gt; &lt;code&gt;plugins&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-plugins"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Known plugin releases and their status.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations"&gt;&lt;/a&gt; &lt;code&gt;revocations&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of &lt;a href="#config-revocations"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Revoked artefact digests or signing keys.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-signature"&gt;&lt;/a&gt; &lt;code&gt;signature&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a href="#config-signature"&gt;object&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;—&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-hosts"&gt;hosts&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-hosts-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Component name (for example gate-one).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-hosts-version"&gt;&lt;/a&gt; &lt;code&gt;version&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Known-good version.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-hosts-hostAPI"&gt;&lt;/a&gt; &lt;code&gt;hostAPI&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Host API constraint, for example &amp;gt;=1.0 &amp;lt;2.0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-externalComponents"&gt;externalComponents&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-externalComponents-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Component name (for example redis).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-externalComponents-role"&gt;&lt;/a&gt; &lt;code&gt;role&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Role in the deployment (session-store, idp, …).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-externalComponents-constraint"&gt;&lt;/a&gt; &lt;code&gt;constraint&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Supported version constraint.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-plugins"&gt;plugins&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-name"&gt;&lt;/a&gt; &lt;code&gt;name&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Reverse-DNS plugin name.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-version"&gt;&lt;/a&gt; &lt;code&gt;version&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Plugin version.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-digest"&gt;&lt;/a&gt; &lt;code&gt;digest&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Artefact digest (sha256:&amp;lt;hex&amp;gt;).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-publisher"&gt;&lt;/a&gt; &lt;code&gt;publisher&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Author/company that published the plugin (shown in a registry page).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-distribution"&gt;&lt;/a&gt; &lt;code&gt;distribution&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;URL where the plugin (artefact + signed manifest + public key) is distributed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-hostAPI"&gt;&lt;/a&gt; &lt;code&gt;hostAPI&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Host API constraint, for example &amp;gt;=1.0 &amp;lt;2.0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-capabilities"&gt;&lt;/a&gt; &lt;code&gt;capabilities&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;array of string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Declared capabilities.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-status"&gt;&lt;/a&gt; &lt;code&gt;status&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;active&lt;/code&gt;, &lt;code&gt;deprecated&lt;/code&gt;, &lt;code&gt;revoked&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Release status. revoked refuses the plugin in enforce mode (when a digest is present).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-plugins-requires"&gt;&lt;/a&gt; &lt;code&gt;requires&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Version constraints on other components, for example {&amp;#34;gate-one&amp;#34;: &amp;#34;&amp;gt;=1.4 &amp;lt;2.0&amp;#34;}.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-revocations"&gt;revocations&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations-digest"&gt;&lt;/a&gt; &lt;code&gt;digest&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Revoked artefact digest.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations-keyId"&gt;&lt;/a&gt; &lt;code&gt;keyId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Revoked signing key id.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations-reason"&gt;&lt;/a&gt; &lt;code&gt;reason&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;misbehaviour, key-compromise, author-request, superseded, …&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations-severity"&gt;&lt;/a&gt; &lt;code&gt;severity&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;low, medium, high.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-revocations-revokedAt"&gt;&lt;/a&gt; &lt;code&gt;revokedAt&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;RFC 3339 timestamp.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect2"&gt;&#10;&lt;h3 id="config-signature"&gt;signature&lt;/h3&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-signature-alg"&gt;&lt;/a&gt; &lt;code&gt;alg&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (fixed: &lt;code&gt;ed25519&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Signature algorithm. Always ed25519.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-signature-keyId"&gt;&lt;/a&gt; &lt;code&gt;keyId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Signing key id; must be in publisherFeed.keys.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-signature-value"&gt;&lt;/a&gt; &lt;code&gt;value&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Ed25519 signature (base64 raw URL) over the JCS canonical form of the feed with the signature removed.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>Usage event</title><link>https://clad-one.github.io/gate-one-doc/latest/docs/config/usage-event/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://clad-one.github.io/gate-one-doc/latest/docs/config/usage-event/</guid><description>&lt;div id="preamble"&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;Generated from &lt;code&gt;schemas/usage-event.schema.json&lt;/code&gt; by &lt;code&gt;scripts/gen-config-docs&lt;/code&gt;. Do not edit this page: edit the schema or the generator.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;div class="paragraph"&gt;&#10;&lt;p&gt;The flat event delivered to subscribed out-of-process plugins. No token, cookie, raw query string, email or username is present.&lt;/p&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="sect1"&gt;&#10;&lt;h2 id="config-root"&gt;Fields&lt;/h2&gt;&#10;&lt;div class="sectionbody"&gt;&#10;&lt;table class="tableblock frame-all grid-all stretch"&gt;&#10;&lt;colgroup&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 20%;"/&gt;&#10;&lt;col style="width: 10%;"/&gt;&#10;&lt;col style="width: 50%;"/&gt;&#10;&lt;/colgroup&gt;&#10;&lt;thead&gt;&#10;&lt;tr&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Field&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Type&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Required&lt;/th&gt;&#10;&lt;th class="tableblock halign-left valign-top"&gt;Description&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-schemaVersion"&gt;&lt;/a&gt; &lt;code&gt;schemaVersion&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer (fixed: &lt;code&gt;1&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Event schema version. Always 1 for this contract.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-type"&gt;&lt;/a&gt; &lt;code&gt;type&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;billing&lt;/code&gt;, &lt;code&gt;audit&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Event family. Only subscribed types are produced.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-ts"&gt;&lt;/a&gt; &lt;code&gt;ts&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Event time, RFC 3339 UTC.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-instanceId"&gt;&lt;/a&gt; &lt;code&gt;instanceId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Stable Gate One node identifier (one WAL per node and type). Minimum length: 1. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-epoch"&gt;&lt;/a&gt; &lt;code&gt;epoch&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;yes&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Producer epoch, changed on restart/migration so consumers can detect a gap. Minimum length: 1. Maximum length: 128.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-tenant"&gt;&lt;/a&gt; &lt;code&gt;tenant&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Auth provider id or logical tenant; empty for shared/public routes. Maximum length: 128.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-subjectId"&gt;&lt;/a&gt; &lt;code&gt;subjectId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Opaque deployment-scoped user identifier: versioned HMAC. Never an email or a raw IdP sub. Pattern: &lt;code&gt;^v[0-9]\.[A-Za-z0-9_-]$&lt;/code&gt;.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-route"&gt;&lt;/a&gt; &lt;code&gt;route&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Normalized route pattern, never the raw URL/query. Maximum length: 512.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-host"&gt;&lt;/a&gt; &lt;code&gt;host&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Request host, without port. Routes are keyed by (host, path): this disambiguates the same path served on several hosts. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-method"&gt;&lt;/a&gt; &lt;code&gt;method&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP method for request/error events. Maximum length: 16.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-status"&gt;&lt;/a&gt; &lt;code&gt;status&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;HTTP status for request/error events. Minimum: 0. Maximum: 599.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-durationMs"&gt;&lt;/a&gt; &lt;code&gt;durationMs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Backend or auth duration in milliseconds. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-bytes"&gt;&lt;/a&gt; &lt;code&gt;bytes&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Response/request size in bytes, as observed by the gateway. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-authResult"&gt;&lt;/a&gt; &lt;code&gt;authResult&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;ok&lt;/code&gt;, &lt;code&gt;anonymous&lt;/code&gt;, &lt;code&gt;denied&lt;/code&gt;, &lt;code&gt;unavailable&lt;/code&gt;, &lt;code&gt;failed&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Authentication outcome for the request or auth action.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-action"&gt;&lt;/a&gt; &lt;code&gt;action&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Auth action: login, login_failed, logout, backchannel_logout, revocation. Audit action: reload, reload_failed, plugin_load. Maximum length: 64.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-detail"&gt;&lt;/a&gt; &lt;code&gt;detail&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Free-text context for audit events (plugin name, reload error). Never PII. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-attrs"&gt;&lt;/a&gt; &lt;code&gt;attrs&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;map of string to string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Bounded billing attributes captured from allow-listed query/body fields (or backend hints). Sensitive names are skipped; values are capped.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-attrsTruncated"&gt;&lt;/a&gt; &lt;code&gt;attrsTruncated&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;boolean&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;True when attrs were capped (too many keys, or a key/value/total exceeded the limit).&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-sessionId"&gt;&lt;/a&gt; &lt;code&gt;sessionId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Opaque RP session id for auth events. Maximum length: 128.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-mcpTool"&gt;&lt;/a&gt; &lt;code&gt;mcpTool&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;MCP tool or operation name, when the event comes from an MCP route. Maximum length: 256.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-units"&gt;&lt;/a&gt; &lt;code&gt;units&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;integer&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Billable/metered units for billing events. Minimum: 0.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-unitType"&gt;&lt;/a&gt; &lt;code&gt;unitType&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string (one of: &lt;code&gt;request&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt;, &lt;code&gt;byte&lt;/code&gt;, &lt;code&gt;mcp_call&lt;/code&gt;)&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Unit kind for billing events.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-requestId"&gt;&lt;/a&gt; &lt;code&gt;requestId&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Gateway request id, for correlation with logs and traces. Maximum length: 128.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;&lt;a id="field-idempotencyKey"&gt;&lt;/a&gt; &lt;code&gt;idempotencyKey&lt;/code&gt;&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;string&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;no&lt;/p&gt;&lt;/td&gt;&#10;&lt;td class="tableblock halign-left valign-top"&gt;&lt;p class="tableblock"&gt;Caller-provided idempotency key, copied only for billing. Maximum length: 128.&lt;/p&gt;&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;</description></item></channel></rss>