Self-custodial key management for Nostr and Bitcoin
  • Rust 96.5%
  • Shell 2.1%
  • Svelte 0.4%
  • JavaScript 0.3%
  • Python 0.3%
  • Other 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-22 18:35:32 -04:00
.github Move the agent bindings off vulnerable nostr and PyO3 releases and check them in CI (#1106) 2026-10-21 08:54:09 -04:00
.well-known Add SECURITY.md documenting threat model (#119) 2026-01-17 22:56:54 -05:00
contrib Let agents call HTTPS APIs with vault secrets they never hold (#1039) 2026-10-14 12:23:42 -04:00
deploy/cdk AWS Enclave Deployment Test (#8) 2025-12-24 16:04:38 -05:00
docs Enforce the relay pin on the CLI and web sockets (#1112) 2026-10-22 16:45:27 -04:00
fuzz fuzz: add a TPM-quote parser target (#743) 2026-07-12 14:39:48 -04:00
keep-agent Drop a compromised CA root from every shipped TLS trust set (#1102) 2026-10-20 19:58:08 -04:00
keep-agent-py Keep secret input out of the agent bindings' error messages (#1107) 2026-10-21 08:54:28 -04:00
keep-agent-ts Keep secret input out of the agent bindings' error messages (#1107) 2026-10-21 08:54:28 -04:00
keep-approval Add the approver phone side to keep-mobile (#1045) 2026-10-14 21:50:22 -04:00
keep-bitcoin Test that FROST wallet descriptors round-trip for every recovery tier count (#1104) 2026-10-20 23:15:58 -04:00
keep-cli Enforce the relay pin on the CLI and web sockets (#1112) 2026-10-22 16:45:27 -04:00
keep-core Refuse an enclave FROST nonce drawn from a degraded source (#1113) 2026-10-22 18:35:32 -04:00
keep-desktop Never auto-approve the event kinds a NIP-46 client names on connect (#1090) 2026-10-19 19:44:15 -04:00
keep-enclave Refuse an enclave FROST nonce drawn from a degraded source (#1113) 2026-10-22 18:35:32 -04:00
keep-frost-net Enforce the relay pin on the CLI and web sockets (#1112) 2026-10-22 16:45:27 -04:00
keep-mobile Report a started bunker as running before start_bunker returns (#1108) 2026-10-21 08:54:32 -04:00
keep-nip46 Ignore NIP-46 requests dated outside the bunker's run (#1092) 2026-10-20 00:22:42 -04:00
keep-web Enforce the relay pin on the CLI and web sockets (#1112) 2026-10-22 16:45:27 -04:00
scripts Add the approver phone side to keep-mobile (#1045) 2026-10-14 21:50:22 -04:00
.dockerignore Debian packages for the keep CLI and keep-web daemon (#892) 2026-07-24 08:02:29 -04:00
.env.example Add CI workflow and .env.example, remove env section from README 2025-12-18 21:30:10 -05:00
.gitignore docs: add mdBook config for the docs.privkey.io portal (#584) 2026-06-10 14:57:28 -04:00
book.toml docs: add mdBook config for the docs.privkey.io portal (#584) 2026-06-10 14:57:28 -04:00
BUILD.md Add build documentation and example configurations (#115) 2026-01-17 09:41:33 -05:00
Cargo.lock Seal the enclave spending policy to the imported key (#1110) 2026-10-22 11:54:57 -04:00
Cargo.toml Release v0.12.2 (#1105) 2026-10-20 21:57:25 -04:00
clippy.toml Check the draws behind the DKG, dealer and refresh secrets too (#1066) 2026-10-17 21:46:20 -04:00
CONTRIBUTING.md Write down the invariants this codebase has broken more than once (#941) 2026-08-04 16:54:06 -04:00
deny.toml Drop a compromised CA root from every shipped TLS trust set (#1102) 2026-10-20 19:58:08 -04:00
Dockerfile.reproducible Copy keep-approval into the release Dockerfiles (#1037) 2026-10-13 23:53:52 -04:00
Justfile Switch license from AGPL-3.0 to MIT (#324) 2026-03-04 21:16:25 -05:00
justfile tests: PSBT migration sweep end-to-end integration test (partial #551) (#573) 2026-06-09 21:09:06 -04:00
LICENSE Switch license from AGPL-3.0 to MIT (#324) 2026-03-04 21:16:25 -05:00
NOTICE Add NIP-49 ncryptsec import/export (#231) 2026-02-18 19:57:40 -05:00
README.md Correct the README's unsafe-code claim and ignore the dev-only nostr-relay-builder advisory (#959) 2026-08-13 15:28:12 -04:00
REUSE.toml Switch license from AGPL-3.0 to MIT (#324) 2026-03-04 21:16:25 -05:00
rust-toolchain.toml Bump rand 0.10, getrandom 0.4, rand_core 0.9, criterion 0.8 (#266) 2026-02-23 08:41:08 -05:00
SECURITY.md Add SECURITY.md documenting threat model (#119) 2026-01-17 22:56:54 -05:00

Keep

Self-custodial key management for Nostr and Bitcoin.

About

Keep is an encrypted vault for Nostr and Bitcoin keys. It stores keys locally with strong encryption, signs remotely via NIP-46 without exposing private keys, and supports FROST threshold signatures so no single device ever holds enough to spend.

Keep runs as a CLI, a desktop app (Linux/macOS/Windows), a mobile library (Android/iOS via UniFFI), a StartOS service for always-on FROST co-signing, or inside AWS Nitro Enclaves for hardware-isolated signing. FROST shares can be distributed across phones, hardware signers, StartOS boxes, and cloud enclaves, then coordinated over Nostr relays for multisig signing.

Ecosystem

Repo Lang Role
this repo Rust Encrypted vault, CLI, desktop app, Nitro Enclave signing, and keep-web headless co-signer
keep-android Kotlin FROST mobile signer with NIP-55 and NIP-46
keep-esp32 C Air-gapped ESP32-S3 hardware signer
keep-node Nix Self-sovereign NixOS security appliance with threshold-OPRF boot unlock
keep-startos TypeScript Always-on FROST co-signer node packaging

Features

  • Encrypted vault: Argon2id + XChaCha20-Poly1305, keys zeroized in RAM
  • Remote signing: NIP-46 bunker mode for any compatible Nostr client
  • Threshold signatures: FROST t-of-n key splitting with distributed key generation (DKG)
  • Network signing: Coordinate FROST signing across devices over Nostr relays
  • Threshold vault unlock: Reconstruct a disk-encryption key at boot from a t-of-n OPRF quorum across TPM-attested holders (powers keep-node)
  • Encrypted secrets store: Keep key-adjacent secrets (BIP39 passphrases, exchange API keys, recovery codes) in the same vault; optionally threshold-seal a secret so its value can only be revealed by a t-of-n OPRF quorum, never from a single device
  • Bitcoin: BIP-86 Taproot addresses, PSBT signing, wallet descriptor coordination
  • Enclaves: AWS Nitro Enclave signing with attestation-based KMS
  • Agent SDK: Constrained signing sessions for AI agents (Python, TypeScript, MCP)
  • Hidden volumes: Plausibly deniable storage, cryptographically undetectable
  • Desktop app: Iced GUI with system tray, QR scanning, NIP-49 import/export

Quick Start

Install the CLI (Rust 1.89+):

cargo install --git https://github.com/privkeyio/keep keep-cli

Building needs pkg-config and libudev (Linux); see BUILD.md for the full per-platform dependency list.

Or build from a clone:

git clone https://github.com/privkeyio/keep
cd keep
cargo install --path keep-cli

Then:

keep init                     # Create encrypted vault (prompts for a password)
keep generate --name main     # Generate a new Nostr key
keep serve --relay wss://bucket.coracle.social  # Start remote signer

Keys are stored encrypted at ~/.keep (override with KEEP_HOME or --path). Set KEEP_PASSWORD to skip the interactive unlock prompt in scripts. Back up your vault with keep backup; see docs/USAGE.md for the full CLI reference, FROST setup, Bitcoin commands, and more.

Documentation

Doc Covers
docs/USAGE.md CLI reference, FROST, Bitcoin, agents, hidden volumes, troubleshooting
keep-web/README.md Self-hosting the headless co-signer (config, auth, API)
docs/SECURITY.md Cryptography and threat model
docs/ENCLAVE.md AWS Nitro Enclave deployment
docs/RELEASE_SIGNING.md Threshold-signed releases
docs/REPRODUCIBILITY.md Reproducible builds
BUILD.md Building from source, system dependencies
CONTRIBUTING.md Contributing guidelines

Development

cargo build --release   # Build
cargo test              # Test
cargo clippy            # Lint

Minimum Supported Rust Version: 1.89.

Security

Pure Rust. Most crates set #![forbid(unsafe_code)]. Three deny it instead, each for a specific reason: keep-core (the mlock-backed secret buffers and the RDRAND entropy probe), keep-cli (Windows file-ACL calls), and keep-agent-ts (the napi macro expands to code that forbid rejects). Every unsafe block outside those three is a compile error. Keys are derived with Argon2id, encrypted with XChaCha20-Poly1305, protected in RAM with Ascon-128a, and locked with mlock(2). FROST uses BIP-340 Schnorr signatures. See docs/SECURITY.md for details.

Keep can threshold-sign software releases with a FROST-Ed25519 group (minisign-compatible), so no single maintainer holds the signing key. See docs/RELEASE_SIGNING.md.

Status

Keep is pre-1.0 and under active development. Public APIs and on-disk formats may change between releases, so pin a version if you build on it. The cryptography has had internal review but no independent third-party audit yet. Use at your own risk, and don't secure more than you can afford to lose.

License

MIT