Cache secure-store public key in identity files.#2533
Conversation
70bf705 to
5a9a6d0
Compare
5a9a6d0 to
bf77937
Compare
There was a problem hiding this comment.
Pull request overview
This PR reduces OS keychain prompts for secure-store identities by caching the derived public key (and associated hd_path) in the on-disk identity TOML, and introducing best-effort lazy migration for legacy identity files.
Changes:
- Extend
Secret::SecureStoreto optionally persistpublic_keyandhd_pathin identity TOML, and use the cache for public-key / signature-hint lookups when it matches. - Populate the cache when creating secure-store identities (
keys generate --secure-store,keys add --secure-store) and add best-effort lazy migration on first read for legacy identity files. - Thread the requested
hd_paththrough signing and address-resolution paths to maximize cache hits; add unit + integration coverage for caching behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/soroban-cli/src/signer/secure_store.rs | Change secure-store save to return a Secret::SecureStore containing cached public key + hd_path. |
| cmd/soroban-cli/src/signer/mod.rs | Allow SecureStoreEntry to use an optional cached public key for hint derivation. |
| cmd/soroban-cli/src/config/sign_with.rs | Use new locator method that passes through hd_path and triggers cache migration when needed. |
| cmd/soroban-cli/src/config/secret.rs | Add cached fields to Secret::SecureStore; use cache in public_key() and signer(); add unit tests. |
| cmd/soroban-cli/src/config/locator.rs | Add read_key_with_secure_store_cache and get_secret_key_with_hd_path (lazy migration + persistence). |
| cmd/soroban-cli/src/config/address.rs | Route muxed-account resolution through the cache-aware locator read. |
| cmd/soroban-cli/src/commands/message/sign.rs | Use cache-aware secret lookup for message signing flow. |
| cmd/soroban-cli/src/commands/keys/generate.rs | Populate cache when generating secure-store keys; add test asserting cache persistence. |
| cmd/soroban-cli/src/commands/keys/add.rs | Update secure-store save call to new signature returning Secret. |
| cmd/crates/soroban-test/tests/it/integration/secure_store.rs | Integration assertion that identity TOML contains cached public_key. |
leighmcculloch
left a comment
There was a problem hiding this comment.
I can't tell, but does the cached public key get updated every time the secret key is read? I don't think so, but I could be wrong. It would be good for that to happen if not, so that the public key cache can't be poisoned through some nefarious actor and then never updated.
| print, | ||
| &self.name, | ||
| &seed_phrase, | ||
| None, |
There was a problem hiding this comment.
Intriguing to me that the add command does not support the --hd-path flag when the generate command does. It doesn't look like that's changing as a part of this PR so it's out of scope to change here, but noticing it here now because this parameter is set to None.
| print, | ||
| &self.name, | ||
| &seed_phrase, | ||
| self.hd_path, |
There was a problem hiding this comment.
The add command doesn't pass an HD path. Is it a bug that the generate command does?
What
public_keyandhd_pathfields to theSecureStorevariant ofSecret, serialized into the identity TOML so address/hint lookups don't need to unlock the OS keychain.read_key_with_secure_store_cacheandget_secret_key_with_hd_pathonlocator::Argsso callers inmessage sign,sign_with, andaddressresolution can pass through the requestedhd_pathand use the cached public key when it matches.Secret::public_keyandSecret::signerto return the cached public key when present (and the requestedhd_pathmatches the cached one), soSecureStoreEntrycan compute the signature hint without re-opening the keychain.Why
On macOS (and other keyring backends), every secure-store operation prompts the user to unlock the keychain. Today even read-only flows trigger prompts:
stellar keys address <name>prompts, even though the public key never changes.stellar tx signprompts to compute the signature hint before prompting again to actually sign.MuxedAccountfrom a secure-store alias prompts.Caching the public key on disk eliminates prompts for read-only address/hint queries entirely.
Close #2446
Known limitations
hd_path. A read at a differenthd_paththan the cached one falls through to the keychain (one prompt) but does not overwrite the cached entry. This keeps the common single-path case fast without invalidating data on multi-path users. To also cachehd_path, add a separate entry withstellar keys add name --hd-path=PATH.keyringcrate's mock builder isolates eachEntryto its own in-memory credential, so the legacy-file → derive → write-back round trip is covered by thesecure_store_key_managementsoroban-test integration test rather than a pure unit test.