docs(gateway): clarify URL allowlist semantics

This commit is contained in:
Peter Steinberger 2026-03-17 00:03:00 -07:00
parent 73ca53ee02
commit e5919bc524
No known key found for this signature in database
7 changed files with 36 additions and 2 deletions

View File

@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
### Changes
- Commands/btw: add `/btw` side questions for quick tool-less answers about the current session without changing future session context, with dismissible in-session TUI answers and explicit BTW replies on external channels. (#45444) Thanks @ngutman.
- Gateway/docs: clarify that empty URL input allowlists are treated as unset, document `allowUrl: false` as the deny-all switch, and add regression coverage for the normalization path.
- Sandbox/runtime: add pluggable sandbox backends, ship an OpenShell backend with `mirror` and `remote` workspace modes, and make sandbox list/recreate/prune backend-aware instead of Docker-only.
- Sandbox/SSH: add a core SSH sandbox backend with secret-backed key, certificate, and known_hosts inputs, move shared remote exec/filesystem tooling into core, and keep OpenShell focused on sandbox lifecycle plus optional `mirror` mode.
- Web tools/Firecrawl: add Firecrawl as an `onboard`/configure search provider via a bundled plugin, expose explicit `firecrawl_search` and `firecrawl_scrape` tools, and align core `web_fetch` fallback behavior with Firecrawl base-URL/env fallback plus guarded endpoint fetches.

View File

@ -2612,6 +2612,8 @@ See [Plugins](/tools/plugin).
- `gateway.http.endpoints.responses.maxUrlParts`
- `gateway.http.endpoints.responses.files.urlAllowlist`
- `gateway.http.endpoints.responses.images.urlAllowlist`
Empty allowlists are treated as unset; use `gateway.http.endpoints.responses.files.allowUrl=false`
and/or `gateway.http.endpoints.responses.images.allowUrl=false` to disable URL fetching.
- Optional response hardening header:
- `gateway.http.securityHeaders.strictTransportSecurity` (set only for HTTPS origins you control; see [Trusted Proxy Auth](/gateway/trusted-proxy-auth#tls-termination-and-hsts))

View File

@ -144,6 +144,8 @@ URL fetch defaults:
- Optional hostname allowlists are supported per input type (`files.urlAllowlist`, `images.urlAllowlist`).
- Exact host: `"cdn.example.com"`
- Wildcard subdomains: `"*.assets.example.com"` (does not match apex)
- Empty or omitted allowlists mean no hostname allowlist restriction.
- To disable URL-based fetches entirely, set `files.allowUrl: false` and/or `images.allowUrl: false`.
## File + image limits (config)

View File

@ -568,6 +568,8 @@ tool calls. Reduce the blast radius by:
- For OpenResponses URL inputs (`input_file` / `input_image`), set tight
`gateway.http.endpoints.responses.files.urlAllowlist` and
`gateway.http.endpoints.responses.images.urlAllowlist`, and keep `maxUrlParts` low.
Empty allowlists are treated as unset; use `files.allowUrl: false` / `images.allowUrl: false`
if you want to disable URL fetching entirely.
- Enabling sandboxing and strict tool allowlists for any agent that touches untrusted input.
- Keeping secrets out of prompts; pass them via env/config on the gateway host instead.

View File

@ -413,9 +413,9 @@ export const FIELD_HELP: Record<string, string> = {
"gateway.http.endpoints.chatCompletions.images":
"Image fetch/validation controls for OpenAI-compatible `image_url` parts.",
"gateway.http.endpoints.chatCompletions.images.allowUrl":
"Allow server-side URL fetches for `image_url` parts (default: false; data URIs remain supported).",
"Allow server-side URL fetches for `image_url` parts (default: false; data URIs remain supported). Set this to `false` to disable URL fetching entirely.",
"gateway.http.endpoints.chatCompletions.images.urlAllowlist":
"Optional hostname allowlist for `image_url` URL fetches; supports exact hosts and `*.example.com` wildcards.",
"Optional hostname allowlist for `image_url` URL fetches; supports exact hosts and `*.example.com` wildcards. Empty or omitted lists mean no hostname allowlist restriction.",
"gateway.http.endpoints.chatCompletions.images.allowedMimes":
"Allowed MIME types for `image_url` parts (case-insensitive list).",
"gateway.http.endpoints.chatCompletions.images.maxBytes":

View File

@ -0,0 +1,20 @@
import { describe, expect, it } from "vitest";
import { normalizeInputHostnameAllowlist } from "./input-allowlist.js";
describe("normalizeInputHostnameAllowlist", () => {
it("treats missing and empty allowlists as unset", () => {
expect(normalizeInputHostnameAllowlist(undefined)).toBeUndefined();
expect(normalizeInputHostnameAllowlist([])).toBeUndefined();
});
it("drops whitespace-only entries and treats the result as unset", () => {
expect(normalizeInputHostnameAllowlist(["", " "])).toBeUndefined();
});
it("preserves trimmed hostname patterns", () => {
expect(normalizeInputHostnameAllowlist([" cdn.example.com ", "*.assets.example.com"])).toEqual([
"cdn.example.com",
"*.assets.example.com",
]);
});
});

View File

@ -1,3 +1,10 @@
/**
* Normalize optional gateway URL-input hostname allowlists.
*
* Semantics are intentionally:
* - missing / empty / whitespace-only list => no hostname allowlist restriction
* - deny-all URL fetching => use the corresponding `allowUrl: false` switch
*/
export function normalizeInputHostnameAllowlist(
values: string[] | undefined,
): string[] | undefined {