encrypted-maps
Encrypted Maps (vetKeys)
EncryptedMaps is a ready-made vetKeys library for access-controlled, end-to-end encrypted key-value storage. Each map is owned by a principal and holds mapKey → value entries; values are encrypted on the client under a vetKey and the canister only ever stores ciphertext. Owners share maps with other principals at three access levels. This is the default starting point for any encrypted-storage app (password manager, encrypted notes, vault).
Use the vetkeys skill instead when you need lower-level primitives: identity-based encryption (IBE), threshold BLS signatures, timelock encryption, or your own symmetric-key scheme.
| Layer | Rust | Motoko | Frontend |
|---|---|---|---|
| Package | ic-vetkeys 0.9 |
ic-vetkeys 0.6 (moc ≥ 1.13.0, core ≥ 2.6.1) |
@icp-sdk/vetkeys 0.5 |
| Backend | export_encrypted_maps_canister! macro |
EncryptedMapsCanister mixin |
@icp-sdk/vetkeys/encrypted_maps |
Use
@icp-sdk/vetkeys(≥0.5), not the legacy@dfinity/vetkeys(frozen at 0.4). Frontend agent/identity come from@icp-sdk/core, not@dfinity/agent.
Concepts
- Map — identified by
(mapOwner: Principal, mapName: bytes). ContainsmapKey → encryptedValueentries.mapNameandmapKeyare byte arrays, max 32 bytes each. - Access rights —
Read,ReadWrite,ReadWriteManage(manage = may grant/revoke others). The owner always has full rights. - Client-side encryption — the frontend fetches a per-map vetKey and encrypts/decrypts locally; the canister enforces access control and stores ciphertext. Sharing a map re-encrypts the map key for the new user automatically.
- Key name & domain separator are immutable once any value is encrypted — they feed key derivation, so changing them makes stored values undecryptable. See pitfalls.