Skip to content

Allow exact local origins while local network access stays off - #2150

Open
vstreame wants to merge 1 commit into
UsefulSoftwareCo:mainfrom
vstreame:feat/allowed-local-origins
Open

vstreame wants to merge 1 commit into
UsefulSoftwareCo:mainfrom
vstreame:feat/allowed-local-origins

Conversation

@vstreame

Copy link
Copy Markdown

Summary

Self-host can now allow a few exact local origins while EXECUTOR_ALLOW_LOCAL_NETWORK stays false. This lets an operator reach one service on the same host, such as a read-only API on 127.0.0.1:<port>, without opening loopback, the LAN or the tailnet to built-in tools like openapi.previewSpec and integrations.detect.

  • Option: HostedHttpClientOptions.allowedLocalOrigins, wired from HostConfig in scoped-executor.ts. Self-host reads it from EXECUTOR_ALLOWED_LOCAL_ORIGINS (comma-separated).
  • Entries: each must be a bare http(s)://<ip literal>[:port] origin. Hostnames are rejected, so DNS never decides. Metadata addresses are refused. A malformed entry stops the server at boot.
  • Matching: a request passes only when its origin equals an entry exactly (scheme, host and port). Everything else is validated as before, and every redirect hop is re-checked.
  • Docs: a new row in the hosted/docker.mdx table. The changeset is minor.

Linked issue

Fixes #2149

Verification

  • bun run format:check: clean.
  • bun run lint: 0 warnings and 0 errors.
  • bun run typecheck: @executor-js/sdk, @executor-js/api and @executor-js/host-selfhost report no errors in changed files. The only errors locally are 20 in fumadb's drizzle adapter (Cannot find module 'drizzle-orm'), the same count on unmodified main, so the cause is my environment.
  • bun run test: packages/core/sdk/src/hosted-http-client.test.ts passes (19 tests, 5 new). The new executor-config.test.ts cases couldn't load locally for the same drizzle-orm reason; CI will run them.
  • e2e: no scenario added. A patched v1.6.10 self-host image has run in production with EXECUTOR_ALLOWED_LOCAL_ORIGINS=http://127.0.0.1:<port>. previewSpec fetched that origin's spec and got HTTP 401 from its data paths. Live HTTP servers on other loopback ports and on the host's private bridge address were refused, while a public URL still went through. The server refuses to boot with http://localhost:<port> as an entry.

New tests:

  • hosted-http-client.test.ts:
    • the listed origin is allowed on any path;
    • other loopback, IPv6, mapped and private targets are blocked, as are a different scheme and localhost;
    • a hostname resolving to the listed IP is refused;
    • a redirect away from the origin is re-checked;
    • entries are normalized.
  • executor-config.test.ts:
    • unset or blank means none;
    • entries are normalized and deduplicated;
    • malformed entries refuse to boot.

Checklist

  • Added a changeset (bun run changeset), or this change needs none.
  • Added or updated tests for the new behaviour.
  • No secrets, credentials, or private data in the diff.

Self-host operators can list exact http(s)://<ip literal>:<port> origins in
EXECUTOR_ALLOWED_LOCAL_ORIGINS. The hosted HTTP client then lets those
through while EXECUTOR_ALLOW_LOCAL_NETWORK=false keeps every other loopback
and private address blocked. Entries must be IP literals, so DNS never
decides; metadata addresses are refused; redirects are re-checked per hop.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature] Self-host: allow exact local origins while EXECUTOR_ALLOW_LOCAL_NETWORK stays off

1 participant