microkv
microkv is a small key-value store for sensitive in-memory data, aiming to miminize its exposure to local attackers who can snoop on your application's virtual memory.
Features
- Key material held in memory-locked, auto-zeroed storage (
memsec). - Entries are encrypted with ChaCha20-Poly1305 under a key derived via
scrypt/argon2/ raw keys. - Anti-tampering through authenticated file header when persisted to disk.
- Other database features: isolated namespaces ("trees"), atomic operations, rollback-on-error transactions, password rotation, and TTl/expiry.
Anti-features
- No plaintext mode — a credential is mandatory.
- No command line interface, server, or networking.
- Does not defend against an attacker with full kernel page-table read/write.
Usage
In your Cargo.toml:
[]
= "0.3.0"
Basic usage
use ;
// open (or create) an encrypted store on disk
let db = open?;
db.put?; // any Serialize value
let name: String = db.require?; // errors if absent
let maybe: = db.get?; // None if absent
db.remove?;
db.save?; // flush to disk
MicroKV derefs to its default namespace, so db.put(..) and db.namespace("").put(..) are the same thing.
In-memory store
use ;
// ephemeral store, never touches disk
let cache = in_memory?;
Using *_with methods, we can also pass a Config for customizations:
use ;
let db = open_with?;
// open read-only: writes return Error::ReadOnly
let ro = open_with?;
There are also create_new / open_existing (and their *_with variants) when you want to fail instead of silently creating or opening.
Namespacing
let users = db.namespace;
let sessions = db.namespace;
users.put?;
sessions.put?; // same key, no collision
let id: = users.get?;
Atomic updates
// read-modify-write under one lock (no get/put race)
db.?;
// insert only if missing
let v: u32 = db.get_or_insert_with?;
// compare-and-swap
let swapped = db.compare_and_swap?;
Transactions
All operations apply together; returning Err rolls everything back. Namespaces are
addressed explicitly ("" is the default).
db.transaction?;
Expiring entries (TTL)
use Duration;
db.put_with_ttl?;
let purged = db.sweep_expired?; // drop expired entries
Iteration
let all_keys: = db.keys?;
let sorted: = db.keys_sorted?;
// decrypt every entry matching a prefix
let active: = db.namespace.prefix?;
Password rotation
// verify the old password, then re-encrypt everything under the new one
db.change_password?;