Skip to content

chore: egress via pre-configured target urls#49

Merged
maxy-shpfy merged 1 commit into
mainfrom
06-30-chore_egress_via_pre-configured_target_urls
Jul 1, 2026
Merged

chore: egress via pre-configured target urls#49
maxy-shpfy merged 1 commit into
mainfrom
06-30-chore_egress_via_pre-configured_target_urls

Conversation

@maxy-shpfy

@maxy-shpfy maxy-shpfy commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

TL;DR

Bundle UI components now reference Tangle API endpoints via logical target objects ({ target: "tangle", path: "..." }) instead of hardcoded absolute URLs. The server resolves the actual base URL from TANGLE_API_URL at runtime, and a new openTargetUrl UI command lets components open deployment-configured URLs without ever knowing the origin.

What changed?

  • host.fetch now accepts HostFetchInput, a union of string | { target: "tangle"; path: string }. Components should use the logical target form; absolute URLs remain accepted only as a compatibility path for trusted internal tooling.
  • A new resolveTargetUrl function builds the full URL from TANGLE_API_URL and validates that the path starts with / and is not protocol-relative.
  • A new UICommand variant { type: "openTargetUrl", target: "tangle", path } lets components request that the host resolve and open a target URL in a new tab. The host calls the new POST /api/agent-bundles/ui-target-url endpoint to resolve the URL server-side before opening it.
  • The hardcoded oasis.shopify.io origin rule has been removed from the egress allowlist; all Tangle egress now goes through the configurable TANGLE_API_URL.
  • PI_PROXY_URL and TANGLE_API_URL are now validated as absolute URLs at startup via readAbsoluteUrl, throwing on misconfiguration rather than silently using a bad value.
  • Default placeholder URLs (https://oasis.shopify.io, https://proxy.shopify.ai, https://tangle.example.com) have been replaced with generic https://api.example.com / https://proxy.example.com examples throughout config, docs, and examples.
  • .env.example now documents server runtime variables (TANGLE_API_URL, TANGLE_TOKEN, PI_PROXY_URL, PI_PROXY_API_KEY, AUTH_JWT_TOKEN_COOKIE_NAME, INSTANCE_PROXY_URL), and the README clarifies that these should be injected via a process manager or secret manager rather than committed.
  • AUTH_JWT_TOKEN_COOKIE_NAME is added to the Turbo env passthrough list.
  • The security findings doc has been updated to remove the now-resolved hardcoded credential finding and replace it with a note on keeping TANGLE_TOKEN as a deployment secret.
  • All example bundle UI components (pipeline-progress.tsx, pipeline-url-input.tsx, sample.js) have been updated to use the logical target form and openTargetUrl instead of hardcoded base URLs and openUrl.

How to test?

  • Run the egress allowlist unit tests: pnpm test in apps/server. The new egressAllowlist.test.ts covers logical target resolution, credential injection, allowlist rejection of non-allowlisted paths, and rejection of malformed paths (missing leading slash, protocol-relative).
  • Start the dev server and load the tangle or tangle-ml-pipeline-optimizer example bundle. Confirm that host.fetch({ target: "tangle", path: "/api/executions/<id>/state" }) proxies correctly and that clicking the pipeline title button resolves and opens the correct URL via openTargetUrl.
  • Set TANGLE_API_URL to an invalid value and confirm the server throws on startup rather than silently using a bad URL.
  • Confirm that POST /api/agent-bundles/ui-target-url with a valid target returns { url } and with an invalid path returns a 400.

Why make this change?

Hardcoding absolute API origins in bundle UI components couples them to a specific deployment environment and leaks internal hostnames into client-side code. By routing through logical targets resolved server-side from TANGLE_API_URL, the same bundle works across environments without modification, credentials and origins stay server-side, and the egress allowlist can enforce path patterns against a single configurable origin rather than a mix of hardcoded ones.

maxy-shpfy commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

@maxy-shpfy maxy-shpfy force-pushed the 06-30-chore_replace_proprietary_terms branch from 148a241 to abb0c23 Compare July 1, 2026 18:52
@maxy-shpfy maxy-shpfy force-pushed the 06-30-chore_egress_via_pre-configured_target_urls branch from 2762e47 to 185fda2 Compare July 1, 2026 18:52
@maxy-shpfy maxy-shpfy force-pushed the 06-30-chore_replace_proprietary_terms branch from abb0c23 to 706e5bd Compare July 1, 2026 19:02
@maxy-shpfy maxy-shpfy force-pushed the 06-30-chore_egress_via_pre-configured_target_urls branch from 185fda2 to 1d61c69 Compare July 1, 2026 19:02
@maxy-shpfy maxy-shpfy marked this pull request as ready for review July 1, 2026 19:13
@maxy-shpfy maxy-shpfy requested a review from a team July 1, 2026 19:57

maxy-shpfy commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Merge activity

  • Jul 1, 9:40 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 1, 9:44 PM UTC: Graphite rebased this pull request as part of a merge.
  • Jul 1, 9:44 PM UTC: @maxy-shpfy merged this pull request with Graphite.

@maxy-shpfy maxy-shpfy changed the base branch from 06-30-chore_replace_proprietary_terms to graphite-base/49 July 1, 2026 21:41
@maxy-shpfy maxy-shpfy changed the base branch from graphite-base/49 to main July 1, 2026 21:42
@maxy-shpfy maxy-shpfy force-pushed the 06-30-chore_egress_via_pre-configured_target_urls branch from 1d61c69 to 2d4c6c1 Compare July 1, 2026 21:43
@maxy-shpfy maxy-shpfy merged commit 017caf4 into main Jul 1, 2026
11 checks passed
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.

1 participant