Overview
The exhaustive field-by-field reference for an SBproxy sb.yml file. Every section listed here corresponds to a config struct in the SBproxy schema, which is the canonical source of truth: if a field appears in the schema, it is supported here, and if a field is documented here, it is in the schema.
For a tour of features with copy-paste configs, see the config overview. For a buyer-facing introduction, see the quick start.
File shape
A SBproxy config file has two required top-level keys (proxy: and origins:) and three optional ones.
proxy: # server-wide settings
...
origins: # map of hostname to per-origin config
"api.example.com":
...
access_log: # optional structured-JSON access log
...
agent_classes: # optional agent-class catalog selection
...
origins: is a map keyed by hostname. The hostname comes from the Host header (with optional SNI fallback when TLS terminates at the proxy). Wildcard prefixes are accepted (*.api.example.com).
proxy: server-level fields
| Field | Type | Default | Notes |
|---|---|---|---|
http_bind_port | u16 | 8080 | HTTP listener port. |
http2_cleartext | bool | false | Detect the HTTP/2 preface on the plain HTTP listener (h2c). |
https_bind_port | u16? | unset | When set, requires tls_cert_file + tls_key_file or acme.enabled: true. |
tls_cert_file | string? | unset | PEM cert path. Ignored when acme is set. |
tls_key_file | string? | unset | PEM key path matching tls_cert_file. |
acme | object? | unset | ACME-managed TLS. |
http3 | object? | unset | Temporarily disabled until native HTTP/3 lands in the proxy engine. The field still parses (enabled, max_streams default 100, idle_timeout_secs default 30) but no listener starts. |
metrics | object? | unset | max_cardinality_per_label (default 1,000). |
admin | object? | unset | enabled, port (9090), username, password, max_log_entries (1000). |
secrets | object? | unset | backend, hashicorp, map, rotation, fallback. |
l2_cache_settings | object? | unset | Shared-state backend. Today driver: redis. Alias: l2_cache. |
cache_reserve | object? | unset | Long-tail cold cache tier. |
messenger_settings | object? | unset | Inter-component event bus. Drivers: memory, redis, sqs, gcp_pubsub. |
trusted_proxies | [string] | [] | CIDRs whose X-Forwarded-For / X-Real-IP / Forwarded headers SBproxy will trust. |
correlation_id | object | defaults | enabled: true, header: X-Request-Id, echo_response: true. |
mtls | object? | unset | client_ca_file, require: true. Requires https_bind_port. |
extensions | map | {} | Opaque map. OSS never parses; extension layers read their own keys. |
origins: per-hostname fields
The origin block sits at origins."<hostname>":. The handler chain below action: is built inside-out at config-load time, so per-request execution does no allocation in the chain-construction path.
| Field | Type | Notes |
|---|---|---|
action | typed object | Required. See Actions below. |
authentication / auth | typed object | Optional. See Authentication. |
policies | [typed object] | Optional. Evaluated in order. |
transforms | [typed object] | Optional. |
request_modifiers / response_modifiers | [object] | Header, body, query, method modifiers. |
cors / hsts / compression | object? | Per-origin CORS, HSTS, compression. |
session / session_config | object? | Cookie-based session config. |
force_ssl | bool | Redirect plain HTTP to HTTPS. |
allowed_methods | [string] | Whitelist. Empty allows all. |
forward_rules | [object] | Inline child origins selected by path, header, or query. |
fallback_origin | typed object | Origin used when the primary upstream fails. |
response_cache | typed object | Per-origin response cache. |
variables | map | Static variables for template interpolation. |
on_request / on_response | [object] | Hooks invoked when a request enters or a response is being returned. |
bot_detection / threat_protection | typed object | Bot detection and IP reputation rules. |
rate_limit_headers | typed object | RFC 9239 header configuration. |
error_pages | typed object | Custom error pages keyed by status or status class. |
traffic_capture / mirror | typed object | Capture and shadow upstream. |
message_signatures | typed object | RFC 9421 HTTP Message Signatures. |
connection_pool | object? | Per-origin upstream pool tuning. |
extensions | map | Opaque. OSS never parses. |
expose_openapi | bool | When true, publish /.well-known/openapi.json and .yaml for this origin. |
rate_limits | object? | Per-origin rate limits. |
default_content_shape | string? | markdown, json, html, pdf, other. |
content_signal | string? | ai-train, search, ai-input. |
token_bytes_ratio | f32? | Markdown projection tokens-per-byte. Defaults to 0.25. |
Actions
Each origin must declare exactly one action. The type: field selects the action; remaining fields are action-specific.
type: | What it does |
|---|---|
proxy | Reverse-proxy to url. The most common action. |
redirect | HTTP redirect (status, url). |
static | Serve static files from a root path. |
echo | Mirror the inbound request back as the response body. |
mock | Return a canned response (status, headers, body). |
beacon | Accept-and-204 for analytics endpoints. |
ai_gateway | Route to the AI gateway. Provider catalogue, routing strategy, guardrails. |
mcp_federation | Aggregate tool catalogues across upstream MCP servers; route tools/call per tool. |
content_negotiate | Two-pass Accept resolution. Auto-prepended when ai_crawl_control or shape transforms are present. |
The proxy field is url (not target).
Authentication
Set authentication: (or its alias auth:) on an origin. Exactly one auth provider per origin.
type: | What it does |
|---|---|
api_keys | Header-based API key check. Keys list is api_keys: (not keys:). |
basic_auth | HTTP basic auth. The legacy basic alias is not accepted. |
bearer | Static bearer-token check. |
jwt | JWT verification with JWKS or static keys. |
digest | RFC 7616 HTTP Digest Auth. |
forward_auth | Forward the request to an external auth service for an allow / deny decision. |
noop | Allow everything. Useful for debugging. |
kya | Skyfire Know-Your-Agent token verifier. |
cap | Crawler Authorization Protocol JWT verifier. |
Policies
policies: is a list of policy entries that evaluate in order.
type: | What it does |
|---|---|
rate_limiting | Token-bucket rate limiter. Set requests_per_second, burst, key:. |
ip_filter | IP allow / block. Use whitelist: and blacklist: (CIDR lists). |
cel_expression | CEL boolean expression on the request context. |
waf | OWASP-style WAF rules. |
ddos_protection | Connection-rate cap with adaptive backpressure. |
csrf | CSRF token enforcement. Requires secret_key. |
security_headers | Stamps a configurable set of security headers on the response. |
ai_crawl_control | Pay Per Crawl. 402 plus Crawler-Payment token redemption. |
exposed_credentials | Cloudflare-style leaked-password check (k-anonymity prefix). |
page_shield | Page Shield equivalent. |
bulk_redirects | Bulk redirect map. |
dlp_catalog | Data-loss-prevention catalogue. |
web_bot_auth | Web Bot Auth (RFC 9421-style signed bot traffic). |
http_framing | Smuggling defence. Drops H2-to-H1 downgrade attacks. |
a2a_envelope | Agent-to-Agent envelope policy with depth cap and cycle detection. |
Lua scripts use function match_request(req, ctx) (not bare code with a global request).
Forward rules
forward_rules: lets one origin dispatch into one of several inline child origins based on path, header, or query.
forward_rules:
- rules:
- path: { exact: /health }
- path: { prefix: /api/ }
- path: { template: /users/{id:[0-9]+}/posts/{post_id} }
- path: { regex: '^/v(?P<version>[0-9]+)/items' }
- header: { name: X-Tenant, value: vip }
- query: { name: debug, value: "1" }
parameters:
- name: id
in: path
required: true
schema: { type: integer, format: int64 }
origin:
action: { type: proxy, url: http://upstream }
Path matchers accept prefix, exact, template, or regex. Precedence when more than one is set: template > regex > exact > prefix. parameters: follow OpenAPI 3.0 Parameter Objects verbatim.
Response cache
| Field | Default | Notes |
|---|---|---|
enabled | false | Global on / off for this origin. |
ttl_secs / ttl | 300 | Accepts 60, 60s, 5m, 2h30m. |
cacheable_methods / methods | ["GET"] | Methods eligible for caching. |
cacheable_status / status_codes | [200] | Status codes eligible for caching. |
max_size | 10000 | In-memory entry cap. Ignored for Redis. |
vary / vary_by | [] | Headers folded into the cache key. |
query_normalize | sort | ignore_all, sort, or allowlist:[...]. |
stale_while_revalidate / swr_secs | unset | Seconds beyond TTL to serve a stale entry while revalidating. |
invalidate_on_mutation | true | Mutating method to a path evicts every cached GET for the same workspace and path. |
Stale replays carry x-sbproxy-cache: STALE.
Cache Reserve and L2 cache
Cache Reserve sits under the per-origin response cache. Fields: enabled, backend, sample_rate (default 0.1), min_ttl (default 3600), max_size_bytes (default 1,048,576). OSS backends: memory, filesystem (with path:), redis (with redis_url:).
L2 cache is the cluster-wide shared backend, configured under proxy.l2_cache_settings:
proxy:
l2_cache_settings:
driver: redis
params:
dsn: redis://localhost:6379/0
Rate limits
Two surfaces: per-policy (policies: entry with type: rate_limiting, token-bucket on a key) and per-origin (rate_limits: block, RFC 9239 middleware mounted ahead of policies).
| Field | Default | Notes |
|---|---|---|
tenant_burst | 2000 | Burst ceiling per tenant. |
tenant_sustained | 1000 | Sustained rps per tenant. |
route_default | 100 | Per-route default rps when no override matches. |
route_overrides | {} | Map keyed by literal path or /prefix/*. First match wins. |
soft_threshold_rps | unset | Above this but below tenant_sustained, requests are tagged but not throttled. |
Throttled responses carry RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, and Retry-After.
Content shape and licensing
| Field | Type | Default | Notes |
|---|---|---|---|
default_content_shape | string? | html | markdown, json, html, pdf, other. |
content_signal | string? | unset | ai-train, search, ai-input. Stamps Content-Signal on 200 responses. |
token_bytes_ratio | f32? | 0.25 | Markdown projection tokens-per-byte. Drives x-markdown-tokens. |
expose_openapi | bool | false | When true, publish /.well-known/openapi.json and .yaml. See OpenAPI emission. |
When content_signal is unset, the proxy stamps TDM-Reservation: 1 instead of asserting a positive Content-Signal.
Extensions (opaque)
Both proxy.extensions and per-origin extensions are opaque maps that OSS never inspects. Extension layers read their own keys by name. This pattern is the standard escape hatch; OSS configs validate-clean against the OSS schema without depending on extension types.
proxy:
extensions:
classifier:
endpoint: "http://127.0.0.1:9500"
origins:
api.example.com:
action: { type: proxy, url: http://localhost:3000 }
extensions:
semantic_cache:
enabled: true
ttl_secs: 1200
See also
- Glossary for the vocabulary used in this reference.
- Config overview for tour-of-features prose with copy-paste configs.
- Extensibility for the CEL, Rego, Lua, JavaScript, and WASM hook surfaces.
- OpenAPI emission for how
expose_openapiand the admin OpenAPI route work.