NOTE: Functionally complete, but still WIP!
a minimal and persistent key-value store designed with security in mind.
microkv is a persistent key-value store implemented in Rust, aiming to maintain a balance between security and performance. It is built out of a yearning to learn more about the intricacies of distributed systems, databases, and secure persistent storage.
While microkv shouldn't be used in large-scale environments that facilitate an insane volume of transactional interactions, it is still optimal for use in a production-grade system/application that may not require the complex luxuries of a full-blown database or even industry-standard KV-store like Redis or LevelDB.
Here are some specific use-cases that you may want to use microkv for:
microkv's underlying map structure is based off of @bluss's indexmap implementation, which offers performance on par with built-in HashMap
's amortized constant runtime, but can also provided sorted key iteration, similar to the less-performant BTreeMap
. This provides a strong balance between performance and functionality.
When reading and persisting to disk, the key-value store Uses bincode
for fast de/serialization of the underlying structures, allowing users to insert any serializable structure without worrying about incurred overhead for storing complex data structures.
microkv acts almost in the sense of a secure enclave with any stored information. First, inserted values are immediately encryped using authenticated encryption with XSalsa20 (stream cipher) and Poly1305 (HMAC) from sodiumoxide
, guarenteeing security and integrity. Encryped values in-memory are also memory-locked with mlock
, and securely zeroed when destroyed to avoid persistence in memory pages.
microkv also provides locking support with RwLock
s, which utilize mutual exclusion like mutexes, but robust in the sense that concurrent read locks can be held, but only one writer lock can be held at a time. This helps remove thread-safey and data race concerns, but also enables multiple read accesses safely.
At its core, microkv is implemented in ~500 LOCs, making the implementation portable and auditable. It does not offer extensions to other serializable formats, or any other user-involved configurability, meaning it will work right out of the box.
(Still WIP)
To see details about how microkv is internally implemented check out the docs/
folder for the following documentation:
You can use microkv as both a library crate for your implementation, or a standalone CLI.
To install locally, simply clone the repository and install with cargo
:
```
$ cargo install microkv
$ git clone https://github.com/ex0dus-0x/microkv $ cargo install --path . ```
Run cargo test
to validate that the test suite works:
$ cargo test
Here's example usage of the microkv
library crate:
```rust extern crate microkv;
use microkv::MicroKV;
struct Identity { uuid: u32, name: String, sensitive_data: String, }
fn main() -> { let unsafepwd: String = "mypassword_123";
// initialize database with (unsafe) cleartext password
let db: MicroKV = MicroKV::new("my_db")
.with_password_clear(unsafe_pwd);
// simple interaction
db.put("simple", 1);
print("{}", db.get::<i32>("simple").unwrap());
db.delete("simple");
// more complex interaction
let identity = Identity {
uuid: 123,
name: String::from("Alice"),
sensitive_data: String::from("something_important_here")
};
db.put("complex", identity);
print("{:?}", db.get::<Identity>("complex").unwrap());
db.delete("complex");
} ```
(TODO)