6.6 KiB
Recovering from a wrong relay key (cp167)
This document is the exact procedure for fixing one specific scenario:
An operator ran
morphit-ops init, the pre-cp167 wizard asked them for "your relay's posting key", they pasted the posting key (encrypted), and now the relay won't work because the chain rejects every operation with "missing required active authority".
It produces a no-trace recovery: no copy of the wrong key remains on the server when you're done.
Background
The Morphit relay broadcasts the following chain operations on the relay account's behalf:
create_claimed_account— signs up a new Morphit usertransfer— sends the welcome bonustransfer_to_vesting— powers up donated BLURTdelegate_vesting_shares— delegates BP for posting
Every one of those requires active authority. The posting key can sign comments and votes, nothing else. If the relay has a posting key, the chain rejects every relay op.
The cp167 wizard fix renames the prompt + the variables + the
internal commentary; any new operator running morphit-ops init
will be asked unambiguously for the active key. This document is
for operators who set up before that fix landed.
Prerequisites on the server
- The operator has the correct active key WIF for the relay
account on hand (a 51-character string starting with
5). - They have shell access to the server as the user that runs
morphit-ops(the same user that ran the install). morphit-opsitself is at the cp167 build or later. Check:
If that returns nothing, pull the latest source and rebuild:morphit-ops --help | grep edit-active-keycd /path/to/morphit git pull npm install npm run build -w apps/ops-cli
The procedure
Run from the same directory that contains morphit.env (the
directory you ran morphit-ops init in):
cd /path/to/morphit
morphit-ops edit-active-key
The command will:
- Read
morphit.env, locate the relay account name and the keystore path. It prints both back so you can sanity-check them. - Read the current keystore, detect that it's encrypted, and print the storage mode.
- Ask: "Was the previous key wrong or compromised?"
Answer
y(yes) — this selects the no-trace rotation path. - Ask you to confirm: "Rotate the active key for @?"
Answer
y(yes). - Prompt for the new active key — paste the 51-character WIF starting
with
5. (It echoes nothing; that's intentional.) - Ask for the storage mode for the new key — choose encrypted (option 1, the default — same as before).
- Ask for a new passphrase. You can reuse the prior passphrase or choose a fresh one. Type it twice.
- The command then:
- Overwrites the prior keystore file (the encrypted posting-key
blob) with random bytes, then zeros, then
fsyncs, thenunlinks it. No.bakfile is created. - Atomically writes the new keystore (encrypted active-key envelope) into the same path with 0600 permissions.
- If the storage mode changed (it shouldn't, both are encrypted),
updates
MORPHIT_RELAY_ACTIVE_KEY_FILEinmorphit.env.
- Overwrites the prior keystore file (the encrypted posting-key
blob) with random bytes, then zeros, then
Verifying after
When the command finishes, the relay account on this server now has:
apps/relay/keystore.json— the new active-key envelope.- No
.bak-*files anywhere inapps/relay/. Verify with:
You should see exactly one file:ls -la apps/relay/keystore*keystore.json.
Then restart the relay:
sudo systemctl restart morphit-relay.service
The relay's startup unlock step:
- Prompts for the passphrase (whatever you typed in step 7 above).
- Decrypts the envelope to get the active-key WIF.
- Derives the public key from that WIF.
- Fetches the current active authority of
@<account>from chain. - Refuses to start if the derived pubkey doesn't appear in the
on-chain active authority's
key_authsarray.
That last check is the hard wall. If you somehow pasted the wrong key again (an active key for a different account, or a posting key by mistake), the relay's startup logs will say something like:
relay: active pubkey BLT... does not appear in @<account>'s
active authority on chain. Refusing to start.
If you see that, re-run morphit-ops edit-active-key with the correct
key. The prior bad key was already wiped — there's no rollback path.
Just paste the right key this time.
What this CAN'T promise
The wipe is a best-effort secure delete at the filesystem level. It
overwrites the file's allocated bytes twice (random, then zeros),
fsyncs, then unlinks. On a stock ext4 or xfs without snapshots or
LVM thin provisioning, that means the prior ciphertext is no longer
readable via the file's old path and the inode is freed. The blocks
themselves are returned to the free pool.
But: if the server uses btrfs, ZFS, or APFS, or if LVM thin pools have snapshots, or if there is full-disk SSD wear-leveling with unallocated reserve, the prior bytes may still exist physically on the device. The only defense against that class of recovery is full disk encryption — which is a baseline you should have anyway for any server holding crypto keys.
For the scenario this document covers — a posting key encrypted by a known passphrase, which is also the wrong type of key to be useful for any attack on the relay account — the practical risk after the wipe is effectively zero.
What about just re-running morphit-ops init instead?
That works but it's heavier:
- It re-prompts for all 20 wizard steps (instance name, tagline, DB URL, fees account, daily ceiling, contact, origin, alt-networks, fee explorers, chat-link explorers, disabled assets, listing fee, SEO, backup, operator tag, Matrix, RPC endpoints, MCP server).
- It rewrites
morphit.env,morphit.config.env, and the keystore. - The old keystore file is replaced by atomic rename — same no-trace
property as
edit-active-key --wipe-prior.
The downside is that any post-launch customizations you made via
morphit-ops edit (origin override, alt-network addresses, SEO copy,
etc.) get overwritten by the wizard's interactive prompts unless you
re-enter them carefully. edit-active-key is the surgical
alternative.
Quick reference
Non-interactive equivalent (CI/scripted):
morphit-ops edit-active-key --wipe-prior
This skips the interactive "was the previous key compromised?" prompt but still asks for the new key, the storage mode, and the new passphrase. (Those are required and have no safe default.)
To force the safe path (keep .bak even for a wrong-key scenario):
morphit-ops edit-active-key --keep-backup
Mutually exclusive with --wipe-prior.