Skip to content

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 20:41
· 78 commits to main since this release
v0.11.0
7de9359

Highlights

FROST groups can spend their own Bitcoin. keep wallet sign signs key-path spends of the addresses keep wallet descriptor gives a watch-only wallet, with co-signers over a relay or with threshold shares held locally. keep bitcoin sign now signs for the addresses keep bitcoin address hands out. This release also fixes DKG and co-signing failures, and records every signature an agent obtains and every secret revealed in the vault's audit log.

Upgrading

  • No protocol change for existing operations. Signing works in groups that mix v0.10.0 and v0.11.0 members: both directions were run against the v0.10.0 release binary over a relay, and each signature verified under both versions. A mixed-version DKG was checked in review rather than run: the extra round packages v0.11.0 sends are ones v0.10.0 already ignores as duplicates.
  • Key-path spends (keep wallet sign over a relay) only pick co-signers that announce support for them, which v0.10.0 does not, and each co-signer must opt in with keep frost network serve --allow-key-path-spend. An opted-in co-signer checks that each input is the group's own output and its sighash type, but does not review the destination or amount: once threshold - 1 co-signers have opted in, any one member holding a share can spend the group's funds. Opt in only where that holds.
  • Vaults open in both directions: v0.11.0 opens vaults written by v0.10.0, and v0.10.0 still opens a vault after v0.11.0 has used it.
  • keep agent mcp grants only the Nostr tools by default. The Bitcoin tools are opt-in and bound to one network and limit: --network enables get_bitcoin_address, --max-amount-sats also enables sign_bitcoin_psbt (it caps what one PSBT may take out of the wallet, fee included), and --allow-address restricts every other output. The NIP-44 operations are no longer granted to an MCP session, which never offered tools for them.
  • A group's outputs are the same scripts on every network, so a signature made for a test-network PSBT also spends those outputs on mainnet. With a test-network descriptor, keep wallet sign refuses unless --any-network is passed, and then warns before asking.

Security

  • NIP-55 auto-signing no longer bypasses expiry or an explicit deny (#1023). With an Auto or Basic sign policy, keep-mobile auto-approved a low-risk request before checking whether the app's access had expired, whether the user had explicitly denied the app, or whether those lookups succeeded. An expired app, an explicitly denied app, or one whose expiry or permissions could not be read now rejects before the sign policy runs, and a permission the user set to Ask now prompts instead of being auto-approved by the policy or a whitelisted relay. A remembered rejection now holds under an Auto or Basic policy. No reject reason string changed: the same deny_expired, deny_timeout, lookup_timeout and deny reasons are now also returned for requests the policy used to auto-approve, and an Ask yields the existing prompt outcome. Android builds pinned to v0.10.0 are affected.
  • Agent signatures are audited (#1019). Every sign_nostr_event and sign_bitcoin_psbt signature from keep agent mcp is recorded in the vault's audit log (keep audit) before it is returned; a signature that cannot be recorded is withheld. Agent signing stops when the log reaches 90,000 entries so an agent cannot make the log unreadable.
  • Secret reveals are audited (#1019). keep secret get records the reveal of a plain secret before showing it, and returns nothing if it cannot. Threshold-sealed reveals now fail closed the same way.
  • The audit log stays openable (#1019). Unlocking reads only the log's last entry, so a long log no longer stops a vault from unlocking; retention and data-key rotation work on a log of any length; a partial line left by a failed write or a crash is cut off.
  • Oversized secrets are refused (#1019). A secret too large to read back is refused when stored instead of being written and then failing every read, and keep secret add reads at most that much from a pipe.
  • Co-signers check sign request participants (#1018). A request whose participants repeat an index, include index 0, leave out the requester or do not match the group's threshold is refused and audited.
  • Agent PSBT signing is bound to a network and limit (#1014). A request naming another network is refused, and the limit counts every output but recognized change plus the fee.
  • Known-answer tests pin the vault KDF, BLAKE2b and BIP-39 (#1020), against independent implementations, so a dependency upgrade that changed their outputs fails CI instead of making existing vaults unreadable.

Fixes

  • keep bitcoin sign signs the wallet's addresses (#1014). It signed only with the secret used directly as a key and with the untweaked key, so PSBTs spending the BIP-86 addresses from keep bitcoin address were signed for zero inputs, and the one address it did sign for produced signatures nodes reject. Each input is now signed with the BIP-341 tweaked key of the wallet key that owns it.
  • DKG no longer times out for the last participant (#1017). Each round subscribes before publishing, and keeps publishing briefly after completing, so a peer that arrives last still receives every package.
  • A co-signer whose share completes a signature sends it (#1018). The other participants, the requester among them, no longer wait out the round and fail over.

Features

  • keep wallet sign for FROST key-path spends of a group's taproot outputs (#1015, #1016), with a confirmation that shows each input, the outputs with change marked, the fee and at most how much leaves the wallet.
  • keep_agent::policy (#1021): the deny-by-default policy engine for the upcoming agent gateway. Library only.

Dependencies

argon2 0.6, blake2 0.11, bip39 3.0 and dirs 7 (#1007, #1009, #1010, #1011), checked against the known-answer tests, and 19 minor and patch updates (#1005). redb stays at 4.1 while the toolchain is on Rust 1.89 (#1006).

Verifying

Binaries are built reproducibly from the tagged commit. SHA256SUMS lists every asset; the maintainer-signed SHA256SUMS.minisig is added after the release is published (see docs/RELEASE_SIGNING.md).