Skip to content

fix: "no wallet key" says why $HEIMDALL_MNEMONIC did not count - #118

Merged
rssh merged 3 commits into
mainfrom
fix/mnemonic-env-diagnosis
Sep 25, 2026
Merged

rssh merged 3 commits into
mainfrom
fix/mnemonic-env-diagnosis

Conversation

@rssh

@rssh rssh commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

An operator reported ERROR Error: no wallet key: set cardano.payment_skey_path (with cardano.wallet_address), or cardano.mnemonic, or $HEIMDALL_MNEMONIC "even when $HEIMDALL_MNEMONIC is set". The resolver reads the variable itself, so it was not set in heimdall's process — and our guide led there: its setup block exports the mnemonic, then ran sudo -u heimdall heimdall register-spo …, and sudo clears the environment.

The error says why. $HEIMDALL_MNEMONIC is read into EnvMnemonic { Unset, Set, NotUnicode } and "no wallet key" ends with the state it met: not set in this process (sudo drops it unless run with --preserve-env=HEIMDALL_MNEMONIC; a service sees only what its unit or container passes), set but blank, or not valid UTF-8 — which var().ok() used to fold into "unset". The text is short and not Debian-specific, because preflight and the reference-script lookup carry it inside their own messages; preflight steps 4 and 11 now point back to step 1 instead of repeating it. EnvMnemonic's Debug is redacted, the phrase is moved rather than copied, and an unreadable variable beside payment_skey_path is refused as two wallet keys instead of silently ignored.

The documented commands pass it without leaking it. Every guide command that needs a mnemonic wallet — quick start, doctor, deploy-registry-ref, all register-spo and deregister-spo steps — uses sudo --preserve-env=HEIMDALL_MNEMONIC -u heimdall heimdall …. The previous env HEIMDALL_MNEMONIC="$HEIMDALL_MNEMONIC" form expanded the phrase into sudo's argv (sudo log, ps); the guide now says so, says key-file operators should not export the variable at all, and warns that systemd logs a skipped export HEIMDALL_MNEMONIC=… line to the journal with the phrase in it. The package's dry run (postinst message, deploy/README.md, guide) is systemd-run -p User=heimdall -p EnvironmentFile=/etc/default/heimdall …, which reads the file with systemd's own parser.

deploy/debian/default is left untouched: it is a conffile, and any edit would prompt every operator who put their mnemonic in it on the next upgrade.

Checked on the roster box (sudo 1.9.15, systemd 255): --preserve-env passes the variable and keeps it out of sudo's argv, an unexported one arrives as unset, plain sudo drops it, and the systemd-run form reads the file as the heimdall user.

…he documented commands pass it

An operator with the mnemonic exported in their shell was told only "no wallet key … or $HEIMDALL_MNEMONIC" by `sudo -u heimdall heimdall register-spo`, exactly as the operator guide wrote the command: sudo clears the environment, and the packaged unit reads the variable only from /etc/default/heimdall, where systemd silently skips an `export` line. The resolver now reads the variable into three states and the error names the one it met — not set in this process (with the sudo and systemd causes and the fix for each), set but blank, or not valid UTF-8, which `var().ok()` used to fold into "unset". The guide's doctor, deploy-registry-ref and register-spo commands now pass the variable through `env`, and the package's dry-run example (default file, postinst, deploy README) uses systemd-run with the unit's EnvironmentFile so it sees the mnemonic the unit will.
@rssh
rssh force-pushed the fix/mnemonic-env-diagnosis branch from 6568887 to afd590e Compare September 25, 2026 11:59
… command line, and the review's other findings

The documented `sudo -u heimdall env HEIMDALL_MNEMONIC="$HEIMDALL_MNEMONIC" …`, in the guide's quick start and now in the "no wallet key" error, expands the seed phrase into sudo's argv, where sudo logs it and ps shows it for the whole run; every such command, and the three wallet-paying ones the first pass missed (the one-step register-spo and both deregister-spo steps), now use `sudo --preserve-env=HEIMDALL_MNEMONIC`, which also reports an unexported variable as unset rather than blank. The resolver's message is shortened to the process-level cause so preflight, which now points steps 4 and 11 back at step 1, and the reference-script lookup do not repeat it; EnvMnemonic's Debug is redacted and the phrase is moved rather than copied; an unreadable variable beside a key file is refused as two wallet keys. deploy/debian/default is restored byte for byte, since it is a conffile and any edit prompts every operator on upgrade, and the guide and README say an `export` line is logged by systemd with the phrase in it.
…and shell history, and no refusal over an unusable value

`status` and `ensure-collateral` read the wallet but were still documented as bare `sudo -u heimdall`, the Docker route passed the phrase as `-e HEIMDALL_MNEMONIC="…"` on the command line, and the quick start's `export HEIMDALL_MNEMONIC="…"` wrote it into shell history; they now use --preserve-env, a pass-through `-e HEIMDALL_MNEMONIC`, and `read -rs`, and the guide says --preserve-env does not hide the environment from a JSON or logsrvd sudo log, where the systemd-run form (now with the unit's WorkingDirectory) passes nothing through sudo. In the code, a non-UTF-8 $HEIMDALL_MNEMONIC beside a key file is no longer refused as a second key, since like a blank one it derives no address; the unset hint names both halves of the sudo case; the phrase is held in Zeroizing and EnvMnemonic no longer derives Clone; the reference-script error puts the `_ref` alternative before the wallet's own error; and the README no longer claims /etc/default/heimdall is outside dpkg's conffiles.
@rssh
rssh merged commit bfe5df1 into main Sep 25, 2026
4 checks passed
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