Sharing redesign: share_gateway service + per-origin cutover, remove cloudflared - #358
Draft
joshalbrecht wants to merge 5 commits into
Draft
Sharing redesign: share_gateway service + per-origin cutover, remove cloudflared#358joshalbrecht wants to merge 5 commits into
joshalbrecht wants to merge 5 commits into
Conversation
…end and scripts Every registered service now owns a real browser origin (locally http://<name>.host-<32hex>.localhost:8421/; future share hostnames follow the same prefix rule on a longer base), routed by the external forwarder. - Remove proxy.py / service_dispatcher.py (SW bootstrap, fetch-prefixing service worker, HTML rewriting, WS shim, cookie-Path scoping) and their tests; drop the register_service_routes wiring and the ServiceName primitive. - Add a same-origin GET/POST /api/browsers passthrough that forwards the browser fleet API to the registered browser service's local backend (503 JSON error when unregistered or unreachable). - layout_ops.py / layout.py now parse service names from service-origin hostnames (first label when a host-<32hex> label sits deeper in), with a drift test pinning the two parsers together; replace-url expectations stay service-relative and are compared by service coordinates. - forward_port.py validates names as origin hostname labels (lowercase alnum/underscore runs joined by single hyphens; host-/agent- prefixes and localhost reserved) on both upsert and --remove, with a new subprocess-driven forward_port_test.py including a scaffold drift guard. - supervisord.conf drops the dead ROOT_PATH=/service/browser env; the browser runner drops its informational ROOT_PATH read.
Add src/origin.ts with deriveServiceOrigin(name) = protocol//name.host/ -- one prefix rule that works locally and on future share hostnames because workspace hostnames nest. All panel-URL builders (serviceRefUrl, getTerminalUrl, buildAgentTerminalUrl, buildSessionTerminalUrl, resolveReplaceUrl, the + menu) now emit absolute service origins. On layout restore, persisted URLs are stale absolute origins from whichever host saved them, so service panel URLs are re-derived from serviceName (preserving any ?query) and agent-terminal URLs are rebuilt from their ttyd dispatch args, keeping saved layouts portable across hosts. The browser fleet listing and the New-browser create POST go through the shell backend's same-origin /api/browsers passthrough (sibling service origins are same-site but not same-origin, and the daemon sends no CORS headers); CreateBrowserModal drops its browserServiceUrl attr. Service panels are cross-origin iframes now, so IframePanel's src-reassignment refresh is the normal path (comments updated).
…ng origins Rewrite build-app (SKILL.md, cross-flow-gotchas, public-url, verify), update-app, service-processes, type-app, web-frontend-testing, and docs/system/workspace-internals.md for the service-per-origin scheme: an app's local origin is http://<name>.<host-id>.localhost:8421/ (share hostnames follow the same prefix rule), nothing rewrites anything, verification curls the registered backend port directly, and the old proxy-era symptoms/sections (duplicated dockview tab bar, Location-header rewriting -- which never actually existed in code -- trailing-slash redirects) are replaced or deleted. Service names are documented as DNS-safe hostname labels with host-/agent- prefixes reserved. preview_wrapper_server.py derives the inner service's sibling origin from location.host by swapping its own leading label (no static src, no path-prefix); serve_isolated_instance.py prints the preview's service name on stdout instead of a /service/... path. The scaffolder reserves localhost and the host-/agent- prefixes so every name it mints registers cleanly. Changelog entries for the agents, dev, system_interface, and browser projects.
New system/services/share_gateway service. While share materials (data/.secrets/share.env, written by the minds app at share-enable) are present, the runner keeps the share stack up: - caddy terminates the workspace's real TLS locally (cert/key under data/.secrets/share_tls/; the relay only ever splices ciphertext) and routes by Host from data/.state/apps.toml -- bare domain to the shell, <service>.<domain> to that service's local backend, unknown-but-plausible service origins to an auto-retrying loading page. The Caddyfile re-renders and hot-reloads (admin API) when the service registry changes. - frpc claims exactly this workspace's domain + wildcard on the region's relay, authenticated by the per-share relay token in its client metadata. - a forward_auth gateway enforces the owner's grants on every request: imbue_machine_session cookie (24h, HS256, workspace-generated secret), grants re-read per request (instant revocation; malformed grants fail closed), per-service grants scoped to their origin, WebSocket/non-GET Origin policy, session cookie stripped before services see the request. Visitors without a session round-trip through the accounts broker; the callback verifies the 60-second audience-bound handoff token (JWKS cache, state nonce, single-use jti) before setting the cookie. The TLS key is generated in-container and never leaves it (CSR-only issuance via the connector); a daily check renews certs within 30 days of expiry. Key, cert, and signing secret persist across unshare for fast re-share. Wiring: supervisord program (share-gateway), pinned sha256-verified caddy 2.11.4 + frpc 0.70.1 in setup_system.sh, share-gateway OOM band, Dockerfile manifest layer, workspace-member registration, docs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The share-gateway service (workspace-terminated TLS + grants enforcement + frp relay tunnel) replaces Cloudflare tunnels for sharing. Deletes system/services/cloudflare_tunnel, its supervisord program, the pinned cloudflared binary install, the Dockerfile manifest layer, its OOM band, and every doc/skill mention; ShareModal now describes machine sharing. Cloudflare references that are unrelated to tunnels (R2 backup storage, the apt-mirror Worker, CAPTCHA notes) stay. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion PR to imbue-ai/mngr-internal#207 (self-hosted, end-to-end-encrypted workspace sharing; spec in the mngr repo's
blueprint/sharing-redesign/)./service/proxy stack deleted, one-rule origin derivation,/api/browserspassthrough, DNS-safe service-name validation.system/services/share_gateway/: in-workspace TLS termination (Caddy), grants-enforcing forward_auth gateway, and the frpc relay tunnel, all gated on injected share materials. Pinned caddy + frpc binaries; supervisord program; OOM band.🤖 Generated with Claude Code