Skip to content

Allow constructing credential stores with supplied keys - #522

Open
Dzejkop wants to merge 6 commits into
codex/uniffi-nextjs-wasm-pocfrom
codex/supplied-storage-keys
Open

Allow constructing credential stores with supplied keys#522
Dzejkop wants to merge 6 commits into
codex/uniffi-nextjs-wasm-pocfrom
codex/supplied-storage-keys

Conversation

@Dzejkop

@Dzejkop Dzejkop commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Allow hosts to construct CredentialStore from resolved StorageKeys, so a browser can supply a passkey PRF-derived database key and a mobile host can resolve its existing device-sealed envelope first.

  • Export StorageKeys::from_bytes and StorageKeys::from_envelope; the store accepts paths and keys without retaining a device keystore or atomic blob store.
  • Keep existing envelope formats unchanged and make envelope deletion an explicit host operation. Store destruction releases its key reference and reports database deletion errors.
  • Update native callers and cover direct-key reopen, wrong-key rejection, initialization retries, key ownership, and destruction.

Validation on the combined stack: 60 native storage tests, the credential-storage integration test, the mock-gateway authenticator construction test, and native Clippy pass.

First of two stacked PRs against the POC (#480). The follow-up updates the web package and demo for the new constructor and moves browser execution into a package-owned worker.


Note

High Risk
Breaking FFI/storage API and changed credential encryption key lifecycle on destroy affect logout, account deletion, and all native hosts that previously used provider-based construction.

Overview
Credential storage is built from resolved StorageKeys plus paths, not from a retained StorageProvider / keystore / blob store. The public UniFFI constructor is CredentialStore::new(paths, keys); StorageKeys::from_bytes supports host-supplied 32-byte keys (e.g. passkey PRF). Device-sealed envelopes are handled separately via new open_or_create_storage_keys and delete_storage_key_envelope in key_envelope.rs.

Logout / teardown semantics change: destroy_storage drops the store’s key handle and best-effort deletes vault/cache files only—it no longer removes account_keys.bin. Hosts must delete the envelope explicitly. A destroyed store cannot be re-initialized in place; callers need a new store (and typically new key resolution). Docs on Authenticator::destroy_storage are updated to match.

Tests and helpers (InMemoryStorageProvider::open_store, testkit FS store) resolve keys first, then construct the store. New coverage exercises direct-key init, wrong-key failure, key refcount on destroy, and best-effort file cleanup.

Reviewed by Cursor Bugbot for commit 54eb012. Bugbot is set up for automated code reviews on this repo. Configure here.

@Dzejkop
Dzejkop added this pull request to stack #524 September 9, 2026 13:47
@Dzejkop
Dzejkop removed this pull request from stack #524 September 9, 2026 13:47
@Dzejkop
Dzejkop force-pushed the codex/supplied-storage-keys branch from e9af717 to b7741dd Compare September 9, 2026 13:52
@Dzejkop
Dzejkop requested a lite review from Copilot September 9, 2026 14:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors credential storage initialization so hosts can construct CredentialStore using already-resolved StorageKeys (direct key or envelope-resolved), rather than requiring the store to retain a keystore/blob-store provider.

Changes:

  • Export StorageKeys constructors for direct bytes and envelope resolution, plus an explicit delete_storage_key_envelope helper.
  • Update CredentialStore construction to accept (StoragePaths, StorageKeys) and stop retaining DeviceKeystore/AtomicBlobStore.
  • Update tests and test utilities to construct stores via resolved keys and validate reopen/wrong-key/destroy semantics.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/walletkit-testkit/src/storage.rs Updates filesystem testkit store construction to resolve StorageKeys up-front and pass them into CredentialStore::new.
crates/walletkit-core/tests/credential_storage_integration.rs Switches integration test store construction to the provider helper (open_store).
crates/walletkit-core/tests/common.rs Adds InMemoryStorageProvider::open_store() helper that resolves keys then constructs a store.
crates/walletkit-core/src/storage/traits.rs Updates module-level docs to reflect host-owned key resolution and direct-key hosts.
crates/walletkit-core/src/storage/tests_utils.rs Adds open_store() helper for storage unit-test utilities.
crates/walletkit-core/src/storage/mod.rs Updates storage docs/exports and makes delete_database_file visible within the storage module.
crates/walletkit-core/src/storage/keys.rs Introduces UniFFI-exported StorageKeys object constructors (from_bytes, from_envelope) and explicit envelope deletion function.
crates/walletkit-core/src/storage/credential_storage.rs Refactors CredentialStore to retain only resolved keys, updates destroy semantics, and expands tests for direct-key behavior.
crates/walletkit-core/src/proof_request_credential_constraints_check.rs Updates tests to use provider.open_store() after constructor changes.
crates/walletkit-core/src/issuers/recovery_bindings_manager.rs Updates tests to use provider.open_store() after constructor changes.
crates/walletkit-core/src/authenticator/with_storage.rs Updates docs/tests to reflect new destruction semantics and store construction changes.
crates/walletkit-core/src/authenticator/mod.rs Updates authenticator tests to construct storage with resolved StorageKeys and adds coverage for that path.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/walletkit-core/src/storage/credential_storage.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

crates/walletkit-core/src/storage/credential_storage.rs:918

  • destroy_storage wraps file-deletion failures for both the vault DB and the cache DB in StorageError::VaultDb, which makes cache cleanup errors indistinguishable/misleading for callers that pattern-match on StorageError variants.
                if let Err(error) = super::delete_database_file(&file) {
                    first_error.get_or_insert_with(|| {
                        StorageError::VaultDb(format!(
                            "delete {}: {error}",
                            file.display()
                        ))
                    });

@Dzejkop
Dzejkop marked this pull request as ready for review September 9, 2026 15:39
@Dzejkop
Dzejkop force-pushed the codex/supplied-storage-keys branch from 82b960c to 13757ea Compare September 9, 2026 15:47
piohei
piohei previously approved these changes Sep 10, 2026
///
/// Removes the encryption keys, vault database, and cache database.
/// Releases the store's key reference and removes the vault and cache databases
/// on a best-effort basis. File deletion failures are logged, not returned.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is best effort then why Error is returned?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Dzejkop
Dzejkop added this pull request to stack #529 September 10, 2026 09:20
@Dzejkop
Dzejkop dismissed piohei’s stale review September 10, 2026 09:37

The merge-base changed after approval.

@Dzejkop
Dzejkop force-pushed the codex/supplied-storage-keys branch from dabb788 to 829ec52 Compare September 10, 2026 09:38
@Dzejkop
Dzejkop force-pushed the codex/supplied-storage-keys branch from 829ec52 to 54eb012 Compare September 10, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants