v1.1.8
[1.1.8] — Unreleased
Security-hardening release. Adds baseline HTTP security headers, a configurable request body-size limit, trusted-proxy client-IP resolution, and expanded secret redaction. Strengthens config validation and admin key safety. No public API breaks. Closes #252–#257.
Security
- CORS deny-by-default (#254): when
CORS_ORIGINSis unset the gateway now emits noAccess-Control-Allow-Originheader, blocking cross-origin access by default. Operators serving a dashboard or UI from a different origin must setCORS_ORIGINSexplicitly (e.g.CORS_ORIGINS=https://dashboard.example.com). WhenCORS_ORIGINSis configured, behaviour is unchanged. - Baseline HTTP security headers (#255): all gateway responses now include
X-Content-Type-Options,X-Frame-Options,Referrer-Policy, andStrict-Transport-Security (HSTS, only on TLS connections)headers to reduce exposure to common web-layer risks. - Request body-size limit (#253):
/v1/*and admin write endpoints reject payloads larger thanConfig.max_request_bytes(default 10 MiB) with HTTP 413 before any LLM call is attempted. Operators can lower or raise the cap inconfig.yaml. - Trusted-proxy client-IP resolution: the deprecated chi
RealIPmiddleware has been replaced by an explicitTRUSTED_PROXIESallowlist.X-Forwarded-For/X-Real-IPheaders are honored only when the immediate peer IP falls within a configured CIDR (default: loopback). Unrecognized peers use the raw connection IP. - Expanded secret redaction: redaction now covers provider-specific and gateway key formats (in addition to the existing email / JWT / AWS key patterns) in structured-log fields and error messages, keeping credential material out of logs.
- Admin config secret masking:
/admin/configresponses now replace secret-valued fields with a masked placeholder so credential material is not readable via the admin API. - Production safety guard: the gateway refuses to start when
GATEWAY_ENV=productionandALLOW_UNAUTHENTICATED_PROXY=trueare set together, preventing accidental unauthenticated exposure in production deployments. - Admin key
Cache-Control: no-store: responses from admin key-management endpoints now includeCache-Control: no-storeto prevent credential caching by intermediaries.
Changed
New()validates config (#256): theGatewayconstructor now runs full config validation (including embedder checks) and returns an error for invalid configuration rather than deferring the failure to request time.- Resilient authentication on counter write failure: a transient failure writing the usage counter no longer causes the gateway to return 401 to an otherwise-valid authenticated key; the error is logged and the request proceeds.
- Word-filter rejection reason: content rejected by the word-filter plugin now returns a generic reason string rather than echoing the matched term.
Fixed
- Proxy error responses: the pass-through proxy no longer includes raw internal error text in HTTP response bodies on base-URL handler failures; callers receive a clean, non-leaking error message.
- CI gates on
release/*branches (#252): theTest,Lint,CodeQL, andgovulncheckCI jobs now trigger onrelease/*pushes in addition tomain, so release branches are validated before tagging.
Documentation
- SECURITY.md, example config, and quickstart (#257): corrected the supported-versions table in
SECURITY.md; removed non-OSS example plugins fromconfig.example.json; fixed the quickstart binary download URL (previously returned 404) to track the latest release; corrected the agent and contributor map.
Contributors
Thanks to everyone who shipped this release:
- v1.1.8 - Security & Trust Hardening (#290) — @MitulShah1
Full changelog: https://github.com/ferro-labs/ai-gateway/blob/v1.1.8/CHANGELOG.md