Skip to content

Latest commit

 

History

History

password_manager

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

VetKey Password Manager (Rust)

The VetKey Password Manager is an example application demonstrating how to use VetKeys and Encrypted Maps to build a secure, decentralized password manager on the Internet Computer (IC). This application allows users to create password vaults, store encrypted passwords, and share vaults with other users via their Internet Identity Principal.

Features

  • Secure Password Storage: Uses VetKey to encrypt passwords before storing them in Encrypted Maps.
  • Vault-Based Organization: Users can create multiple vaults, each containing multiple passwords.
  • Access Control: Vaults can be shared with other users via their Internet Identity Principal.

Build and deploy from the command line

Prerequisites

  • Install Node.js
  • Install icp-cli: npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
  • Install the Rust toolchain, then add the WASM target: rustup target add wasm32-unknown-unknown

(Optionally) choose a different master key

This example uses test_key_1 by default. To use a different available master key, change the init_args value in icp.yaml before deploying.

Install

git clone https://github.com/dfinity/examples
cd examples/rust/vetkeys/password_manager

Deploy

icp network start -d
icp deploy

Internet Identity sign-in runs against the Internet Identity canister deployed on the local network (ii: true in icp.yaml). If signing in fails, update the local network launcher with icp network update and restart the network.

Open the frontend URL printed by icp deploy.

To run the frontend in development mode with hot reloading (after icp deploy):

npm run dev

When done, stop the local network to free up the port for other projects:

icp network stop

Example components

Backend (backend/)

An Encrypted Maps-enabled Rust canister that securely stores passwords.

Note. The entire canister is generated by the ic_vetkeys::export_encrypted_maps_canister!(...) macro: the canister owns the MemoryManager and passes Encrypted Maps its four Memory instances, and the macro emits the #[init]/#[post_upgrade] plus every #[query]/#[update] endpoint. Because the macro is the single source of the endpoint set, the exposed Candid matches what the @icp-sdk/vetkeys frontend expects by construction. See backend/src/lib.rs. When you need to extend the standard endpoints with your own state or invariants, see the password_manager_with_metadata example, which layers per-password metadata on hand-written endpoints.

Frontend (frontend/)

A Svelte application providing a user-friendly interface for managing vaults and passwords. It talks to the backend through the @icp-sdk/vetkeys Encrypted Maps client.

Derived-key caching

EncryptedMaps derives and caches the vetKey material used to encrypt/decrypt values. As of @icp-sdk/vetkeys 0.5.0 this cache is in memory by default (discarded on page reload). This example opts into cross-reload persistence with IndexedDbDerivedKeyMaterialCache, giving the store a per-identity namespace (vetkeys-<principal>) so one identity's keys are never served to another on the same origin, and it calls clearCache() on the EncryptedMaps instance on logout to drop the cached material.

Verifying clearCache() on logout. clearCache() empties the cache's object store; it does not delete the database, so an empty vetkeys-<principal> database remaining in the list is expected (an empty store holds no usable key material). To check it:

  1. Open DevTools → Application → IndexedDB.
  2. Expand vetkeys-<principal> → derived-key-material. While logged in and after opening a vault it holds one or more entries; after logout it should hold 0.
  3. DevTools caches this view — click Refresh database after logging out, otherwise stale entries appear to linger.

You will also see an unrelated icp-sdk-<host> database (object store subnetNodeKeys): that is the agent's cache of public subnet node keys, not key material, and is safe to ignore.

Updating the Candid interface

backend/backend.did defines the backend's public interface. If you change the backend's public API, regenerate it:

icp build backend && candid-extractor target/wasm32-unknown-unknown/release/backend.wasm > backend/backend.did

Limitations

This example app does not implement key rotation, which is strongly recommended in a production environment. Key rotation involves periodically changing encryption keys and re-encrypting data to enhance security. In a production app, key rotation would be useful to limit the impact of a potential key compromise, or to limit access when users are added to or removed from sharing.

Additional resources