Skip to content

fix(fly): require SPRITES_TOKEN on the fly target - #682

Open
kylemclaren wants to merge 1 commit into
yc-software:mainfrom
kylemclaren:fix/fly-sprites-token-gate
Open

fix(fly): require SPRITES_TOKEN on the fly target#682
kylemclaren wants to merge 1 commit into
yc-software:mainfrom
kylemclaren:fix/fly-sprites-token-gate

Conversation

@kylemclaren

@kylemclaren kylemclaren commented Aug 26, 2026

Copy link
Copy Markdown

The problem

A new fly deployment does not start. The core application stops immediately after each start. It writes this error:

Error: missing or insecure required core secrets: SPRITES_TOKEN
    at loadConfig (file:///app/src/config.ts:594:11)

The core application makes 10 attempts to start. Then Fly stops the machine. The other four services do not deploy, because the core deploys first.

I found this problem when I deployed to Fly for the first time.

The cause

The file deploy/core/fly.toml sets SANDBOX_BACKEND = "sprites". The file src/deployment/secret-schema.ts makes SPRITES_TOKEN a necessary secret when SANDBOX_BACKEND has the value sprites. Thus the core application needs SPRITES_TOKEN when it starts.

The CLI does not know this. The secret gate in cli/src/secrets.ts looks for the value of SANDBOX_BACKEND in two places:

  1. In env.core in the file qm.config.jsonc.
  2. In TARGET_ENV_DEFAULTS.

The fly entry in TARGET_ENV_DEFAULTS declares only HARNESS. It does not declare SANDBOX_BACKEND. A scaffolded configuration does not set SANDBOX_BACKEND in env.core. Thus the CLI does not find the value.

The result is four failures:

  • qm setup does not ask the operator for the token.
  • qm check does not show the token in the list of necessary secrets.
  • qm secrets push does not send the token to the core application.
  • qm up deploys a core application that cannot start.

The fly target permits only the sprites sandbox backend. You can see this in cli/src/providers.ts. Thus each fly deployment needs this secret.

Why the tests did not find the problem

The test FLY_TEMPLATE_ENV_DEFAULTS stays in sync with deploy/core/fly.toml examines one direction only. It reads each entry in the constant. Then it makes sure that deploy/core/fly.toml sets that entry to the same value. It does not read the entries in deploy/core/fly.toml. Thus an entry that the constant does not declare stays hidden.

The test the sprites token is a catalog secret when the sandbox backend is sprites uses the aws target only. No test used the fly target.

The correction

The correction has two parts:

  1. Add SANDBOX_BACKEND: "sprites" to FLY_TEMPLATE_ENV_DEFAULTS. The constant now agrees with the template that it mirrors.
  2. Use one function for the fly defaults and the aws defaults. Before this change, only the aws branch let an explicit sandbox.backend replace the default. The two branches now behave in the same way.

The new tests

I added two tests to cli/test/secrets.test.ts:

  • The first test makes sure that the fly target needs SPRITES_TOKEN. It uses three configurations: no sandbox block, a sandbox block with an app, and a sandbox block with an explicit backend.
  • The second test reads deploy/core/fly.toml. It finds each variable that controls a secret. For each of these variables, the test makes sure that FLY_TEMPLATE_ENV_DEFAULTS declares the variable with the same value. This test looks in the direction that the older test does not examine. It prevents this class of problem in the future.

Both new tests fail before the correction. Both new tests pass after the correction.

The effect on operators

SPRITES_TOKEN becomes a necessary secret for each fly deployment. qm setup asks for the token. qm check shows the token. qm secrets push sends the token to the core application.

A fly deployment that operates correctly today already has this secret in its core application. Such a deployment does not change.

The tests that I ran

I ran the CLI test suite before the change and after the change:

  • Before the change: 515 tests, 512 pass, 3 fail.
  • After the change: 517 tests, 514 pass, 3 fail.

The same three tests fail in both conditions. These three tests fail because of my environment, not because of this change. Two of them (init refuses to generate keys into an absent but Git-tracked .env and init refuses a present tracked .env before writing the scaffold) depend on the Git state of the checkout. One of them (the packed npm artifact creates and operates a standalone deployment repository) runs npm pack, which my sandbox restricts.

I updated four test fixtures for the fly target. These fixtures now supply SPRITES_TOKEN. The fixtures were correct to fail: they described a deployment that could not start.

npm run typecheck and eslint show no errors for the changed files.

What I did not do

I did not add the token to qm doctor as a live check. The Sprites API can show if a token is correct. A subsequent change can add this check.

A related note

I used the Sprites API to make sure that a token was correct before I put it in the deployment:

curl -H "Authorization: Bearer $SPRITES_TOKEN" https://api.sprites.dev/v1/sprites

An organization token for Fly does not operate here. The token must come from sprite login. The reference cli/templates/deployment/references/fly.md does not tell the operator this. The same reference tells the operator to prove the agent computer with fly machine exec. This instruction is correct for Fly Machines. It is not correct for sandboxes that run on Sprites. These two items are documentation problems. I did not correct them in this change.


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

deploy/core/fly.toml sets SANDBOX_BACKEND = "sprites", which makes
SPRITES_TOKEN a required core secret at config load. The CLI never saw
that value: the secret gate resolves SANDBOX_BACKEND from env.core and
then from TARGET_ENV_DEFAULTS, and the fly entry declared only HARNESS.

setup never prompted for the token, check never listed it, secrets push
never delivered it, and up deployed a core that crash-looped to its
restart limit with "missing or insecure required core secrets:
SPRITES_TOKEN".

Declare SANDBOX_BACKEND in FLY_TEMPLATE_ENV_DEFAULTS so the constant
matches the template it mirrors, and share one resolver between the fly
and aws defaults so an explicit sandbox.backend overrides both.

The existing sync test only walked the constant and asserted fly.toml
agreed, so a missing entry was invisible. The new test walks the other
direction over every template env that gates a secret.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvEqtztffzduM5H7Hrt9JJ
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