Gate signed-out document requests at the edge instead of flashing the app-shell skeleton#975
Merged
Merged
Conversation
… app-shell skeleton Signed-out visitors to the cloud app were SSR'd the authenticated app-shell skeleton (sidebar + card grid) until a client-side /account/me round trip 401'd and swapped in the login page — a loading preview of an app they were never going to reach. The sealed session cookie can be verified in the worker itself (unseal + JWT against cached JWKS; no per-request round trip), so a new request middleware does exactly that for document navigations: - signed-out -> 302 to /login?returnTo=<path> before any app HTML is served; an invalid cookie is also cleared (its presence is what routes the production root past the marketing site) - signed-in -> pass through, persisting any rotated sealed session (refresh tokens are single-use) - /login is a real route now; returnTo travels with the CSRF state cookie through the login flow and the callback resumes the original path (validated to same-origin relative, never /api) - /cloud (the marketing CTA target, previously a 404) redirects into the app root Signed-in loads get faster too: AuthProvider seeds optimistic state from a new non-HttpOnly display-only auth-hint cookie it maintains on every confirmed /account/me, so the shell paints without waiting on the probe; the resolved answer remains the authority. Logout and the gate clear the hint alongside the session. Unknown paths get a real 404 page (notFoundComponent) instead of mounting the auth gate's skeleton. The unauthenticated-skeleton e2e (the red repro for this report) is now green and grew scenarios for the deep-link round trip, open-redirect rejection, signed-in passthrough, and the 404 page.
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-cloud | 22a0783 | Jun 12 2026, 03:52 PM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
executor-marketing | 22a0783 | Commit Preview URL Branch Preview URL |
Jun 12 2026, 03:51 PM |
Contributor
Cloudflare previewTorn down — the PR is closed. |
@executor-js/cli
@executor-js/config
@executor-js/execution
@executor-js/sdk
@executor-js/codemode-core
@executor-js/runtime-quickjs
@executor-js/plugin-file-secrets
@executor-js/plugin-graphql
@executor-js/plugin-keychain
@executor-js/plugin-mcp
@executor-js/plugin-onepassword
@executor-js/plugin-openapi
executor
commit: |
RhysSullivan
commented
Jun 12, 2026
Replace the seven hand-tracked primitive fields with a memoized resolved state: useMemo on the atom value gives the identify and hint-cookie effects a dependency that tracks real query transitions, and the context value is memoized so consumers don't re-render on unrelated renders.
…ookie
The state parameter already round-trips through the identity provider
and is authenticated by the wos-login-state CSRF cookie, so the
destination rides inside it — base64url(JSON { nonce, returnTo }) — and
the wos-login-return-to cookie goes away. The callback re-validates the
decoded returnTo like any other untrusted path.
The state parameter is now base64url(JSON { nonce, returnTo }), so the
scenario decodes it and asserts the nonce inside instead of expecting
the raw hex value.
Five new scenarios over the real WorkOS emulator: - auth-hint: a confirmed /account/me writes the hint and the NEXT load paints the real shell while the probe is held open; logout clears the hint with the session. - session-gate: an invalid wos-session is cleared on the way to /login (not just redirected); /cloud routes into the app both signed out and signed in; and a session whose access token no longer verifies is refreshed in-flight — the rotated sealed session reaches the browser, the spent one is revoked server-side (real single-use refresh tokens), and the rotated one keeps working. The stale-token path unseals the real session cookie with the same iron-webcrypto sealing the WorkOS SDK uses, corrupts the JWT signature, and reseals — exercising the gate's refresh branch without waiting out a real expiry.
This was referenced Jun 12, 2026
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.
Problem
The same signed-out visit to the cloud root, with the auth probe held open so the loading window is visible —
mainon the left, this branch on the right:Signed-out visitors to executor.sh/cloud were shown the authenticated app-shell skeleton (sidebar nav + content-card grid) until a client-side
/account/meround trip returned 401 — at which point the page swapped to a login UI. Every unsigned-out load flashed the wrong shell.Fix
Three layers, each standing alone:
1. SSR auth gate (
apps/cloud/src/auth/ssr-gate.ts)A TanStack Start request middleware (last in the
requestMiddlewarechain instart.ts) that intercepts GET/HEAD document navigations before any React renders. It verifies the sealedwos-sessioncookie directly in the worker — unseal + JWT check against a cached JWKS — so there is no per-request WorkOS round trip except on token refresh. Signed-out visitors get a302 /login?returnTo=<path>before any app HTML is generated. An invalid cookie is cleared on the way out (on executor.sh, the cookie's mere presence routes/past the marketing page). WorkOS refresh tokens are single-use, so a rotated sealed session is re-set on the response./cloud(the path marketing CTAs link to) was previously a 404; it now redirects into the app.2. Auth-hint cookie (
packages/react/src/multiplayer/auth-hint.tsx)A non-HttpOnly companion to the sealed session: a display-only Schema-validated snapshot of the authenticated identity.
AuthProviderwrites it whenever/account/meconfirms a session and reads it back at mount to seed optimistic "authenticated" state — so signed-in loads paint the real shell immediately without waiting for the probe. Cloud logout and the SSR gate clear it server-side. The resolved/account/mealways wins.3.
/loginroute with redirect-backA proper
/loginpage (apps/cloud/src/routes/app/login.tsx) with?returnTo=round-trip plumbing: the SSR gate setsreturnTo, the login handler encodes it into the OAuthstateparameter beside the CSRF nonce (base64url(JSON { nonce, returnTo })— no extra cookie), and the callback decodes it from the validated state and redirects there. AisSafeReturnTovalidator (relative-only, no//, no/api) prevents open-redirect abuse at both ends. Signed-in visitors hitting/loginare bounced straight back.notFoundComponentadded — unknown paths now show a real 404 page instead of a skeleton or a blank app.Test coverage
e2e/cloud/unauthenticated-skeleton.test.ts— 4 scenarios:/loginimmediately with no app-shell flash (screenshot verified during the in-flight window)/tools→ gate → login → callback →/tools) + open-redirect rejection/loginbouncee2e/cloud/auth-hint.test.ts— 2 scenarios: a confirmed/account/mewrites the hint and the next load paints the real shell while the probe is held open; logout clears the hint with the session.e2e/cloud/session-gate.test.ts— 3 scenarios: an invalidwos-sessionis cleared on the way to/login(along with the hint);/cloudroutes into the app signed out and signed in; and a session whose access token no longer verifies is refreshed in-flight against the WorkOS emulator — the rotated sealed session reaches the browser, the spent one is revoked server-side (real single-use refresh tokens), and the rotated one keeps working. The stale-token path unseals the real cookie with the same iron-webcrypto sealing the WorkOS SDK uses, corrupts the JWT signature, and reseals — exercising the refresh branch without waiting out a real expiry.apps/cloud/src/auth/return-to.test.ts+login-state.test.ts— unit tests covering theisSafeReturnTo/safeReturnTo/loginPathvalidators and the OAuth state envelope codec (round-trip, URL-safe alphabet, junk-tolerance).All gates pass:
bun run format:check,bun run lint,bun run typecheck,bun run test.