Provision the runtime configuration — the certificates token scoped to the motir-marketing app and the base-domain variables, set on both Fly apps and read back from the platform (manual)
Opened by Zhu Yue ·
Put the configuration the ADR named into the platform BEFORE the code that reads it ships — a value nothing reads yet is inert, so provisioning first costs nothing and means the lifecycle code meets a configured system on its first request. No pull request; done on your confirmation with the platform readings pasted here.
What to provision
| variable | app | value | why it is a secret here and not a file |
|---|---|---|---|
FLY_CERTS_TOKEN | motir-core | a Fly token scoped to the motir-marketing app — fly tokens create deploy -a motir-marketing (name it motir-core-certificates) | it can add and remove certificates on the live marketing site; it is never the token either app deploys with (flyMachines.ts's rule for FLY_FLEET_API_TOKEN) |
FLY_CERTS_APP | motir-core | motir-marketing | the app whose certificates the adapter manages — configuration, not code, so a rename of the app is a secret change |
MOTIR_PUBLIC_TENANT_DOMAIN | motir-core | the base domain the domain card registered | the server composes tenant addresses from it |
Not here, and why: motir-marketing reads the base domain at BUILD time as NEXT_PUBLIC_MOTIR_TENANT_DOMAIN, the way lib/siteOrigin.ts is configured — a NEXT_PUBLIC_* value is inlined by next build, so it travels in fly.toml's [build.args] and the Dockerfile's ARG, which is a code change in the router card, not a secret. Setting it as a Fly secret would do nothing (.env.example says so for the app origin).
Steps
- Mint the token and PROVE its scope before storing it: with only that token in
FLY_API_TOKEN, runfly certs list -a motir-marketing(must succeed) andfly certs list -a motir-core(must be refused). If a deploy token cannot list certificates, mint the narrowest token that can and record which kind — the claim that a deploy token suffices is a hypothesis until this step. fly secrets set --stage FLY_CERTS_TOKEN=… FLY_CERTS_APP=motir-marketing MOTIR_PUBLIC_TENANT_DOMAIN=<base> -a motir-core—--stageso no machine restarts for values nothing reads yet; the next deploy (any merge) carries them in.- Store the token in the team password manager under the same name, with the scope test's output.
- Read back from the platform:
fly secrets list -a motir-core— paste the three names and digests. (After the first deploy that follows,fly ssh console -a motir-core -C 'env' | grep -E 'FLY_CERTS|TENANT_DOMAIN'is the reading that the RUNNING app has them — that reading belongs to the verification task, because it needs a merge.)
Acceptance criteria
fly secrets list -a motir-coreshowsFLY_CERTS_TOKEN,FLY_CERTS_APPandMOTIR_PUBLIC_TENANT_DOMAIN; the output is pasted, dated.- The scope test's two command outputs are pasted: the token lists certificates on
motir-marketingand is refused onmotir-core. - The token is recorded in the password manager under
motir-core-certificates, and no token value appears on this card or in any repository. - No secret was set on
motir-marketing, and no restart ofmotir-corewas triggered (--stage).
Context refs
- the decision — the variable table
motir-core/lib/orchestrator/adapters/fly/flyMachines.ts— the token-scoping rule;motir-marketing/.env.example·fly.toml[build.args]— why the marketing side is a build arg- Fly —
https://fly.io/docs/flyctl/tokens-create-deploy/·https://fly.io/docs/flyctl/secrets-set/(--stage)
Discussion
No comments yet.
Adding to this discussion signs you in on app.motir.co and brings you back to this request.