DO NOT MERGE INTO A RELEASE SIGNED WITH THE NEW KEY. See below.
The previous release root (z6Mkkid…q7ur, pinned 2026-07-02) was exposed
in a chat transcript and is treated as compromised. It signs both OTA
manifests and the app catalog, so anyone holding it could sign updates
the fleet would install.
Pins the new key in trust::anchor and moves EXPECTED_DID in all three
signing/publishing scripts.
ORDERING IS CRITICAL — nodes pin the OLD key:
* The release CARRYING this commit must be signed with the OLD key.
That is the only signature a node running the previous binary will
accept, and it is what installs the binary pinning the new key.
* Only the release AFTER that may be signed with the new key.
* Signing this release with the new key makes every node reject it,
ending OTA fleet-wide and requiring hands-on recovery per node.
sign-catalog.sh moves in the same commit, so the app catalog must also be
re-signed with the new key once this ships, or nodes accept the binary
and reject the catalog.
Key verified before pinning: the hex and the did:key are the same
keypair, checked with a base58 decoder round-tripped against the previous
known-good pair. An earlier candidate hex (cb830e13…) was rejected
because it decoded to a different DID than the one supplied — pinning it
would have made every node reject every future update.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
44 lines
2.0 KiB
Bash
Executable File
44 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# One-step release-catalog signer.
|
|
#
|
|
# Run: bash scripts/sign-catalog.sh
|
|
# Then: paste your 24-word release master mnemonic, press Enter, then Ctrl-D.
|
|
#
|
|
# It signs releases/app-catalog.json in place and checks the signature was made
|
|
# by the expected release-root key. Your mnemonic is read from the terminal only
|
|
# (never stored, never in shell history, never passed to Claude).
|
|
set -euo pipefail
|
|
|
|
REPO="/home/archipelago/Projects/archy"
|
|
CATALOG="$REPO/releases/app-catalog.json"
|
|
EXPECTED_DID="did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT"
|
|
|
|
# Use ONLY the prebuilt signer. If it isn't ready, stop cleanly — never compile
|
|
# here (compiling caused the earlier hangs). Claude builds it in the background.
|
|
BIN="/tmp/archy-sign-bin/release/archipelago"
|
|
if [[ ! -x "$BIN" ]]; then
|
|
echo "⏳ The signer isn't ready yet — Claude is still building it."
|
|
echo " Wait until Claude says 'READY', then run this again. Nothing was changed."
|
|
exit 0
|
|
fi
|
|
SIGN=("$BIN" ceremony sign "$CATALOG")
|
|
|
|
echo "════════════════════════════════════════════════════════════════"
|
|
echo " Paste your 24-word release master mnemonic below, press Enter,"
|
|
echo " then press Ctrl-D on a new line."
|
|
echo "════════════════════════════════════════════════════════════════"
|
|
"${SIGN[@]}"
|
|
|
|
# Verify the signature is present and made by the expected key.
|
|
echo
|
|
if grep -q "\"signed_by\": \"$EXPECTED_DID\"" "$CATALOG" \
|
|
&& grep -q '"signature":' "$CATALOG"; then
|
|
echo "✅ SUCCESS — catalog signed by the correct release-root key."
|
|
echo " Tell Claude \"signed\" and it will commit + push for you."
|
|
else
|
|
echo "❌ Something is off — the catalog is NOT signed by the expected key."
|
|
echo " Expected signer: $EXPECTED_DID"
|
|
echo " Do NOT commit. Check the mnemonic and re-run, or ask Claude."
|
|
exit 1
|
|
fi
|