web: optional edge-only forward-auth origin for publications

Merged
LU
14d ago
+39-3

Summary

dev backend stacks are tailnet-only, so freestyle's edge can't call their /api/freestyle/forward-auth, and protected publications on dev never work. pointing CMUX_VM_PUBLICATION_AUTH_ORIGIN at a public tunnel doesn't fix it either: browsers then sign in on the tunnel, but the stack sends every redirect to its own .ts.net origin (requestOrigin), so the session cookie is on the wrong host and the sign-in handoff hangs.

this adds an optional CMUX_VM_PUBLICATION_FORWARD_AUTH_ORIGIN. when set, it's the origin pushed to freestyle as the forward-auth target; browsers still sign in on CMUX_VM_PUBLICATION_AUTH_ORIGIN. same validation as the auth origin (bare https:// origin, checked at startup), and a set but malformed value yields an empty url that ensureSharedForwardAuth rejects before provider i/o, instead of falling back. unset (prod today) nothing changes.

operator-only: it's read from server env, never from a request, same as the auth origin.

Testing

  • bun test tests/vm-publication-workflows.test.ts -t forward-auth: 2 pass, including the new test (override wins, malformed override fails closed).
  • live on a dev stack (tag port-share): auth origin = the stack's .ts.net origin, forward-auth origin = a cloudflared quick tunnel on the dev VM. publish → active, signed-out GET 302s to /cloud/access, sign in as a team member, page loads; 30/30 signed-out requests got the 302 with the tunnel on the VM (with the tunnel on my mac in NZ, round trips of 1.2-2s tripped freestyle's 1.5s timeout and showed its 503).

the tunnel itself isn't part of this PR. if dev stacks should get this by default, that's a devbackendd change (per-tag extra env + a public edge for one stack); happy to write it if you want it.

Changelog

none


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Adds an optional CMUX_VM_PUBLICATION_FORWARD_AUTH_ORIGIN so development stacks can expose the freestyle forward-auth endpoint at a reachable origin without moving browser sign-in there.

  • When set, the edge targets this origin for forward-auth; browsers still sign in on CMUX_VM_PUBLICATION_AUTH_ORIGIN, keeping the session cookie on the right host.
  • Uses the same validation as the auth origin; a set but malformed value fails closed instead of falling back, and a blank value counts as unset.
  • Read from server env only, never from a request. Unset in production, where behavior is unchanged.

Summary by CodeRabbit

  • Configuration
    • Added an optional setting to route publication forward-auth requests through a separate HTTPS origin, for example when the configured authentication origin is unreachable. If unset, requests continue to use the configured authentication origin.
    • The setting accepts only a bare HTTPS origin, without credentials, path, query, or fragment. Blank values are treated as unset; invalid values do not produce a forward-auth URL. Service-token behavior remains unchanged.