Skip to content

feat(dev): portless named .localhost origins for the local auth stack - #271

Merged
Zach Dunn (zachdunn) merged 6 commits into
mainfrom
claude/localhost-auth-portless-01c7b6
Jul 19, 2026
Merged

feat(dev): portless named .localhost origins for the local auth stack#271
Zach Dunn (zachdunn) merged 6 commits into
mainfrom
claude/localhost-auth-portless-01c7b6

Conversation

@zachdunn

Copy link
Copy Markdown
Member

Why

Agents (and humans) struggled to reach signed-in pages locally: the session cookie minted by the auth worker on 127.0.0.1:8788 never spanned web (:4321) or api (:8787), localhost vs 127.0.0.1 were different cookie sites, and stale/prod origin fallbacks tripped the strict CSP. Modeled on the ~/Code/sunny and ~/Code/releases portless setups.

What

pnpm dev:stack now runs through portless:

Service URL
web https://uploads.localhost
auth https://auth.uploads.localhost
api https://api.uploads.localhost

The shared .uploads.localhost cookie parent makes the Better Auth session span all three workers exactly like .uploads.sh in prod. Worktrees get branch-prefixed hosts; the cookie parent anchors on the last two labels so nothing else changes.

  • deriveCookieDomain: multi-label *.localhost.<name>.localhost parent; bare x.localhost stays host-only
  • PORTLESS_ORIGIN_RE: multi-label + proxy-port (:1355) origins
  • dev-session gate: accepts a matched *.localhost pair (loopback by spec); real-TLD origins never enable the bypass; origin header now checked against configured WEB_ORIGIN
  • resolveSignedInOrigins: in dev, supervisor-injected PUBLIC_* origins beat a stale apps/web/.dev.vars (prod untouched)
  • dev-stack: pre-starts the proxy (task runners must — no TTY means no sudo prompt), unprivileged-port fallback, re-execs with the portless CA so Node fetch verifies TLS, resolves origins via portless get; PORTLESS=0 keeps the legacy pinned loopback ports (dev GitHub OAuth callback path)
  • docs/local-dev.md: new portless section

Verified

  • pnpm dev:stack boots and its smoke passes end-to-end over the named origins (dev-session → get-session → API membership → file listing)
  • Agent browser panel: minted a dev session from the web origin and rendered the signed-in /account/workspaces shell (files, usage, membership) — the original pain case
  • pnpm check, pnpm typecheck, full pnpm test (1589 passing)
  • Debug note: a root-owned ~/.portless/ca.srl (from an old sudo proxy run) silently produced 0-byte per-host certs and TLS aborts; removing it fixed cert issuance. pnpm exec portless doctor didn't catch this.

pnpm dev:stack now runs web/auth/api through portless at
https://uploads.localhost, https://auth.uploads.localhost, and
https://api.uploads.localhost (worktree branch names become prefixes).
The shared .uploads.localhost cookie parent lets the Better Auth session
span all three workers like .uploads.sh does in prod, so signed-in pages
work in local browsers — including agent browser panels — without the
cross-port cookie workarounds.

- deriveCookieDomain: multi-label *.localhost hosts share the
  last-two-label parent; bare x.localhost stays host-only
- trusted origins: PORTLESS_ORIGIN_RE accepts multi-label and
  proxy-port (:1355) origins
- dev-session gate: accepts a matched *.localhost pair (loopback by
  spec); real-TLD origins still never enable the bypass
- resolveSignedInOrigins: in dev, supervisor-injected PUBLIC_* origins
  beat a stale apps/web/.dev.vars
- dev-stack: pre-starts the proxy (with unprivileged-port fallback),
  re-execs with the portless CA for Node fetch, resolves origins via
  portless get; PORTLESS=0 keeps the legacy pinned loopback ports
  (dev GitHub OAuth callback path)
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
uploads-api cadefca Commit Preview URL

Branch Preview URL
Jul 19 2026, 09:02 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
uploads-auth 800766b Commit Preview URL

Branch Preview URL
Jul 19 2026, 09:50 PM

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 19, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
uploads-web 42619af Commit Preview URL

Branch Preview URL
Jul 19 2026, 10:10 PM

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (2)
  • coderabbit:review
  • review
🚫 Excluded labels (none allowed) (1)
  • wip

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c8320100-aca8-4563-8ba8-bc93637fa665

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/localhost-auth-portless-01c7b6

Comment @coderabbitai help to get the list of available commands.

Mirrors the sibling repos' *.local.buildinternet.dev zones: providers that
reject *.localhost redirect URIs can run the stack at
https://auth.local.uploads.sh etc. via PORTLESS_TLD=sh
PORTLESS_NAME=local.uploads (+ portless hosts sync). Trusted outside
production only, https only; the dev-session bypass stays .localhost-only,
so dev:stack skips its cookie smoke in this mode.
…ildinternet.dev

local.uploads.sh shared prod's registrable domain, so prod's
Domain=.uploads.sh session cookies would ride into local dev stacks (and
local software could set prod-scoped cookies). The shared infra zone has no
production cookies to overlap — same reasoning as the sibling repos.
deriveCookieDomain anchors the zone parent across worktree prefixes; the
uploads.sh DNS records were deleted.
@zachdunn
Zach Dunn (zachdunn) merged commit 0c14a76 into main Jul 19, 2026
4 checks passed
@zachdunn
Zach Dunn (zachdunn) deleted the claude/localhost-auth-portless-01c7b6 branch July 19, 2026 22:11
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