Skip to content

A deployment issues its own console key, so the form asks for nothing - #33

Merged
thankywal merged 1 commit into
mainfrom
deploy-asks-for-nothing
Sep 3, 2026
Merged

thankywal merged 1 commit into
mainfrom
deploy-asks-for-nothing

Conversation

@thankywal

Copy link
Copy Markdown
Owner

The bug, from the deploy form itself

Cloudflare's Create and deploy step makes every name in .dev.vars.example a required field. That file listed one — CONSOLE_KEY — and the browser refused to submit without it:

Please fill out this field.

Someone who has just pressed a deploy button is held there and asked for a password to a thing that does not exist yet, with nothing on the page to say what a good answer would be. One box, and it is the wall.

The change

.dev.vars.example lists nothing, and the deployment makes the key itself.

  • packages/runtime/src/console-key.ts resolves the key: the CONSOLE_KEY secret, else KV, else one it mints and keeps. Read every time rather than cached per isolate — replacing the key has to end the sessions it opened, and an isolate answering with an hour-old key would keep them alive.
  • runSetup mints it and installs the web owner row on every deployment, not only the ones without Telegram. The browser door is not a fallback for people who have no Telegram account; it is the ordinary way in.
  • The setup page prints the key until somebody signs in, then stops. The end state is a record — the first successful claim — not a timer. Until then nobody owns the deployment and its owner has no other way to learn the key; after it, printing the key on a public page would hand it to whoever opens the address next.
  • A key the owner configured is never echoed back. They already know it, and that page is public.
  • missingConfiguration collapses to the half-Telegram case. Nothing else is ever missing, which is the point.
  • A short CONSOLE_KEY stops nothing. It used to refuse to finish setup — a working deployment taken down over an optional setting somebody typed hopefully into a box. The page says it is being ignored instead.
  • muxel init no longer refuses an install that names no door, for the same reason: the command line was insisting on something the Worker had stopped needing.

Proved live, not reasoned

wrangler dev --local on an empty D1 with nothing configured:

GET /health after the first page ready, missing: []
key it issued itself 28 characters, on the page
POST /admin/claim with it 200 + token
console API with that token 200
the page afterwards no longer prints the key
the same key again 200
a wrong key 401

Then CONSOLE_KEY set as a secret on the same database: the issued key 401, the chosen key 200, the page still silent.

Tests

951 passing. The tests that pinned the old design were rewritten to pin the new one, and the load-bearing one is stricter than what it replaced:

it("asks a new owner for nothing at all", () => {
  expect(DEPLOY_FORM).toEqual([])
})

DEPLOY_FORM is read out of .dev.vars.example, so a name added back there is a wall put back in front of every new owner, and this fails. A companion test holds the five READMEs to the same file, and another refuses any <code>SETTING</code> in a walkthrough step before the deploy.

The smoke run now walks the path a new owner actually walks — open the address, read the key off the page, sign in, watch the page stop printing it — instead of setting a secret no owner will set. It still proves the override takes a leaked key back.

Docs

Five READMEs, docs/TELEGRAM-SETUP.md, docs/DEPLOY-RECOVERY.md and the console's own onboarding move with it. "Before you start" is two accounts and nothing to invent.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FMFyy3oXb9u2AxoYQKRXHu

Cloudflare's deploy form makes every name in `.dev.vars.example` a REQUIRED
field. The file listed one, `CONSOLE_KEY`, and that was enough to stop a new
owner dead: they had pressed a deploy button, and the browser held them at
"Please fill out this field" asking for a password to a thing that did not
exist yet, with nothing to tell them what a good answer looked like.

So the file lists nothing, and the deployment makes the key itself.

- `console-key.ts` resolves it: the CONSOLE_KEY secret, else KV, else one it
  mints and keeps. Read every time rather than cached per isolate, because
  replacing the key has to end the sessions it opened.
- `runSetup` mints it and installs the web owner row on every deployment, not
  only the ones without Telegram. The browser door is not a fallback for people
  who have no Telegram account; it is the ordinary way in.
- The setup page prints the key until somebody signs in, and then stops. The
  end state is a record — the first successful claim — not a timer: until then
  nobody owns the deployment and its owner has no other way to learn the key;
  after it, printing the key would hand it to whoever opens the page next.
- A key the owner configured is never echoed back. They know it, and that page
  is public.
- `missingConfiguration` collapses to the half-Telegram case. Nothing else is
  ever missing, which is the whole point.
- A short CONSOLE_KEY stops nothing now. It used to refuse to finish setup —
  a working deployment taken down over an optional setting somebody typed
  hopefully into a box. The page says it is being ignored instead.
- `muxel init` no longer refuses an install that names no door, for the same
  reason: the command line was insisting on something the Worker stopped
  needing.

The smoke run walks the path a new owner actually walks — open the address,
read the key off the page, sign in, watch the page stop printing it — instead
of setting a secret no owner will set. It also proves the override still takes
a leaked key back.

Verified live on `wrangler dev --local` against an empty D1 with nothing
configured: health ready, key issued at 28 characters, claim 200, console API
200, page stops printing it, same key still signs in, wrong key 401. Then with
CONSOLE_KEY set on the same database: issued key 401, chosen key 200.

Five READMEs, the chat setup instructions, the recovery guide and the console's
own onboarding all move with it. The before-you-start list is two accounts and
nothing to invent.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FMFyy3oXb9u2AxoYQKRXHu
@thankywal
thankywal merged commit b22481e into main Sep 3, 2026
2 checks passed
@thankywal
thankywal deleted the deploy-asks-for-nothing branch September 3, 2026 13:12
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