pulumi config set --secret writes ciphertext into Pulumi.dev.yaml, which is
committed, alongside the encryptionsalt. This stack's secrets provider is a
passphrase, and the passphrase is the empty string documented three lines above
it in the README. That combination is not encryption — it is the token spelled
differently, readable by anyone with access to this repo.
pulumi-cloudflare falls back to CLOUDFLARE_API_TOKEN when cloudflare:apiToken
is absent from config, so __main__.py is unchanged and so is pulumi up. The
token simply stops living in git.
The empty passphrase is left as it is. It protects nothing precisely because
nothing secret is in config any more, and that is what makes it harmless; the
notes now say to change the secrets provider before adding a secret at rest.
This does NOT un-expose the existing token. The value is still readable in this
branch's history at 94dd775, and history rewriting would not help either, since
it has been pushed since 2026-09-09. Only rotating the credential closes that;
notes/CLOUDFLARE.md now covers how, including checking Last used before
deleting the token, which is the only record of whether it was ever used.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fctc-website-under-construction pulumi-worker
This deploys the fctc under construction page into a Cloudflare worker using Pulumi.
Bootstrap
Ran this from /infra/
uv init --no-readme --no-workspace
uv add pulumi pulumi-cloudflare
uv lock
pulumi logout # this is here incase you were already logged into some pulumi backend
pulumi login --local # this keeps Pulumi's state in a local file. see ./notes/STATE.md
export PULUMI_CONFIG_PASSPHRASE=""
pulumi stack init dev # setting the passphrase to an empty string for now. see ./notes/PASSPHRASE.md
export CLOUDFLARE_API_TOKEN=... # NOT pulumi config. see ./notes/CLOUDFLARE.md
pulumi config set accountId # see ./notes/CLOUDFLARE.md
The Cloudflare token goes in the environment, not the config
pulumi config set --secret writes the value into Pulumi.dev.yaml as ciphertext, and
that file is committed. With the local backend the stack's secrets provider is a
passphrase, and this stack's passphrase is the empty string, documented three lines above.
Committed ciphertext plus a committed salt plus a documented passphrase is not encryption
— it is the token, spelled differently, readable by everyone with access to this repo.
pulumi-cloudflare reads CLOUDFLARE_API_TOKEN from the environment when
cloudflare:apiToken is absent, so nothing in __main__.py changes and neither does
pulumi up. The token just stops living in git.
The empty passphrase is not the problem and does not need fixing. It protects nothing
because nothing secret is in config any more, which is the arrangement that makes it
harmless. It becomes a problem again the moment someone runs pulumi config set --secret
— so if this stack ever does need a secret at rest, change the secrets provider first.
See ./notes/PASSPHRASE.md.
Brind it up
pulumi up