chore(deploy): seed a minimal .env — stop pre-seeding maskable vars (#70)
The bitspire-env activation seeds .env only when ABSENT (never refreshes on redeploy), and env WINS over the pairing seed — so any value written at first boot is frozen for the disk's life and silently masks the seed's source. That's how a dead relay.aiolabs.dev and a provisioned VITE_OPERATOR_PUBKEYS made stale installs "work" while a fresh machine broke. Seed ONLY image-baked, non-maskable values (model, fiat, ELECTRON_FORCE_PROD, DISPLAY, empty VITE_SPIRE_SEED placeholder). Relay + server pubkey come from the seed; operator pubkey + fee config come from LNbits over the transport — so those keys are no longer pre-seeded at all. VITE_RELAY_URL / VITE_LNBITS_SERVER_PUBKEY are emitted only when the operator deliberately pins them via the Nix options (an explicit override). Also drops the inert RELAY_URL/LNBITS_SERVER_PUBKEY lines from /etc/bitspire/config.env (never loaded — EnvironmentFile is forced to .env). Verified: built sintra-installed .env template is 5 lines, 0 maskable vars. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
7bc718f9e3
commit
42c0d3e9ca
3 changed files with 35 additions and 29 deletions
36
flake.nix
36
flake.nix
|
|
@ -186,30 +186,34 @@
|
|||
allowReboot = false;
|
||||
};
|
||||
|
||||
# Env template — runtime secrets provisioned via provision-atm.sh.
|
||||
# Identity fields are intentionally empty so a fresh disk image
|
||||
# boots cleanly into the "needs provisioning" state; provision-
|
||||
# atm.sh SSHes in and overwrites with real values.
|
||||
# Minimal env template (aiolabs/bitspire#70 remnant hygiene).
|
||||
# Seed ONLY image-baked, non-maskable values. Everything else the
|
||||
# ATM needs comes from the pairing SEED (relay, lnbits_npub, bunker)
|
||||
# or from LNbits over the transport (operator pubkey, fee config) —
|
||||
# so we must NOT pre-seed those keys. A present-but-empty
|
||||
# VITE_RELAY_URL / VITE_LNBITS_SERVER_PUBKEY / VITE_OPERATOR_PUBKEYS
|
||||
# is a masking hazard: env WINS over the seed, and this activation
|
||||
# only writes when .env is ABSENT, so any value written at first
|
||||
# boot is frozen for the life of the disk. Leaving the keys out
|
||||
# entirely lets the seed/transport be the sole source.
|
||||
#
|
||||
# VITE_RELAY_URL + VITE_LNBITS_SERVER_PUBKEY seed EMPTY by default
|
||||
# (relayUrl defaults to ""), so the pairing seed drives the relay
|
||||
# + server pubkey (aiolabs/bitspire#70). A non-empty `relayUrl`
|
||||
# option pins a machine to a specific relay (seeded here, wins over
|
||||
# the seed via env-first precedence) — otherwise leave it blank.
|
||||
# VITE_RELAY_URL / VITE_LNBITS_SERVER_PUBKEY are emitted ONLY when
|
||||
# the operator deliberately pins them via the Nix options (non-empty
|
||||
# default ""), which is an explicit override that wins over the seed.
|
||||
system.activationScripts.bitspire-env = ''
|
||||
mkdir -p /var/lib/bitspire
|
||||
if [ ! -f /var/lib/bitspire/.env ]; then
|
||||
cp ${pkgs.writeText "bitspire-env-default" ''
|
||||
VITE_RELAY_URL=${config.services.bitspire.relayUrl}
|
||||
VITE_LNBITS_SERVER_PUBKEY=
|
||||
VITE_SPIRE_SEED=
|
||||
VITE_APP_ID=
|
||||
VITE_OPERATOR_PUBKEYS=
|
||||
cp ${pkgs.writeText "bitspire-env-default" (''
|
||||
VITE_LAMASSU_MACHINE_MODEL=${machineModel}
|
||||
VITE_LAMASSU_FIAT_CODE=${fiatCode}
|
||||
VITE_SPIRE_SEED=
|
||||
ELECTRON_FORCE_PROD=1
|
||||
DISPLAY=:0
|
||||
''} /var/lib/bitspire/.env
|
||||
'' + pkgs.lib.optionalString (config.services.bitspire.relayUrl != "") ''
|
||||
VITE_RELAY_URL=${config.services.bitspire.relayUrl}
|
||||
'' + pkgs.lib.optionalString (config.services.bitspire.lnbitsServerPubkey != "") ''
|
||||
VITE_LNBITS_SERVER_PUBKEY=${config.services.bitspire.lnbitsServerPubkey}
|
||||
'')} /var/lib/bitspire/.env
|
||||
chmod 600 /var/lib/bitspire/.env
|
||||
chown bitspire:bitspire /var/lib/bitspire/.env
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue