Skip to content

Fix two config gaps that break a from-scratch Fly deployment - #4

Merged
16francej merged 1 commit into
mainfrom
fix/fly-sandbox-backend-and-portal-identity
Jul 29, 2026
Merged

Fix two config gaps that break a from-scratch Fly deployment#4
16francej merged 1 commit into
mainfrom
fix/fly-sandbox-backend-and-portal-identity

Conversation

@16francej

@16francej 16francej commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Two gaps in what the CLI hands the runtime. Each independently breaks a Fly deployment, and both were hit in sequence standing one up from scratch today.

1. Core never receives SANDBOX_BACKEND on Fly

Core refuses to start in production unless SANDBOX_BACKEND is set (src/config.ts), but only the AWS backend emitted it (cli/src/backends/aws.ts). A Fly deploy therefore crash-loops to its 10-restart cap:

Error: SANDBOX_BACKEND must be set explicitly in production — use sprites, aws, or local.
    at loadConfig (file:///app/src/config.ts:535:11)

Fixed in sandboxCoreEnv, which is the layer all three backends derive core env from (fly.ts:181, docker.ts:483, aws.ts:240), rather than in one backend:

  • an explicit sandbox.backend now always reaches core, on every target
  • a fly target with a sandbox.app defaults to sprites — the substrate sandbox.app already describes, matching the fallback AWS uses for the same case
  • docker is unchanged — its sandboxes are local rather than sprites, so it still emits nothing unless sandbox.backend is explicit
  • env.core.SANDBOX_BACKEND still wins, since configuredEnv is applied after sandboxEnv

2. PORTAL_IDENTITY_SECRET never reaches admin or web-ui

It was declared for core and portal only, but admin and web-ui also sign portal identities through the chassis. When it is absent the chassis silently substitutes a different key:

// plugins/chassis/src/env.ts
export const PORTAL_IDENTITY_SECRET = process.env.PORTAL_IDENTITY_SECRET ?? CORE_SIGNING_SECRET;

Core verifies with portalIdentitySecret ?? secret and does have the real key, so every admin and web-ui request fails the identity check. The portal fails closed on that, which surfaces as "Admin is temporarily unavailable", and web chat returns 401 sign in — neither pointing at a key mismatch.

Verified against a live deployment: with the secret delivered, GET /v1/admin/whoami returns {"isAdmin":true,"role":"org_admin",...}; without it, the same request 401s.

auth is deliberately not included — it imports the chassis (so it logs the same fallback line) but never signs a portal identity.

Tests

Three tests in cli/test/secrets.test.ts, each confirmed to fail without the corresponding source change:

  • PORTAL_IDENTITY_SECRET reaches all four services in the trust boundary
  • a fly deployment tells core which substrate to boot
  • an explicit sandbox.backend wins, and non-fly targets keep their own default

deploy/core/fly.toml is regenerated from the derive function, so the byte-for-byte test passes.

npm run typecheck clean, oxlint clean, 474/475 CLI tests pass. The one failure — "AWS secret rotation holds the deploy lease across the complete write set"fails identically on main without this change and is unrelated.

Worth considering separately

The chassis fallback is what made #2 invisible: a signing/verifying key mismatch should refuse to boot in production rather than degrade to 401s at runtime. Changing that is a behavioural change with wider blast radius, so it is not in this PR.

Needs an adversarial review pass — I wrote it, so I am the wrong reviewer.

🤖 Generated with Claude Code


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

A Fly deployment could not boot its core, and could not reach Admin or web
chat once it did. Both are gaps in what the CLI hands the runtime.

Core refuses to start in production unless SANDBOX_BACKEND is set, but only
the AWS backend ever emitted it. Fly and docker both derive their core env
from sandboxCoreEnv, so the variable is set there instead of in one backend:
a configured sandbox.backend now always reaches core, and a fly target with
a sandbox app defaults to the sprites substrate that sandbox.app describes.
Docker keeps its previous behaviour, since its sandboxes are local rather
than sprites, and an explicit env.core.SANDBOX_BACKEND still wins.

PORTAL_IDENTITY_SECRET was declared for core and portal only, yet admin and
web-ui also sign portal identities through the chassis. With the variable
absent the chassis silently falls back to CORE_SIGNING_SECRET while core
verifies with the real key, so every admin and web-ui request fails the
identity check. The portal fails closed on that, surfacing as "Admin is
temporarily unavailable" with nothing pointing at a key mismatch.

deploy/core/fly.toml is regenerated from the derive function.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@16francej
16francej merged commit 54bc256 into main Jul 29, 2026
15 checks passed
@16francej
16francej deleted the fix/fly-sandbox-backend-and-portal-identity branch July 29, 2026 21:22
ReganBell pushed a commit that referenced this pull request Jul 29, 2026
A Fly deployment could not boot its core, and could not reach Admin or web
chat once it did. Both are gaps in what the CLI hands the runtime.

Core refuses to start in production unless SANDBOX_BACKEND is set, but only
the AWS backend ever emitted it. Fly and docker both derive their core env
from sandboxCoreEnv, so the variable is set there instead of in one backend:
a configured sandbox.backend now always reaches core, and a fly target with
a sandbox app defaults to the sprites substrate that sandbox.app describes.
Docker keeps its previous behaviour, since its sandboxes are local rather
than sprites, and an explicit env.core.SANDBOX_BACKEND still wins.

PORTAL_IDENTITY_SECRET was declared for core and portal only, yet admin and
web-ui also sign portal identities through the chassis. With the variable
absent the chassis silently falls back to CORE_SIGNING_SECRET while core
verifies with the real key, so every admin and web-ui request fails the
identity check. The portal fails closed on that, surfacing as "Admin is
temporarily unavailable" with nothing pointing at a key mismatch.

deploy/core/fly.toml is regenerated from the derive function.

Co-authored-by: YC Labs <yclabs@YCs-Mac-Studio.local>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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