# Vault Implementation Plan (Technical Appendix)

This document is a technical reference for contributors and maintainers of the Vault crate. It covers advanced implementation details, design rationale, and data models. For a high-level overview and usage, see [`vault.md`](vault.md) and [`architecture.md`](architecture.md).

---

## Table of Contents
- [Design Principle: Stateless & Session APIs](#design-principle-stateless--session-apis)
- [Data Model](#data-model)
- [Module & File Structure](#module--file-structure)
- [Advanced Notes](#advanced-notes)

---


> **Design Principle:**
> **The vault crate will provide both a stateless (context-passing) API and an ergonomic session-based API.**
> This ensures maximum flexibility for both library developers and application builders, supporting both functional and stateful usage patterns.

## Design Principle: Stateless & Session APIs

The `vault` crate is a modular, async, and WASM-compatible cryptographic keystore. It manages an encrypted keyspace (multiple keypairs), provides cryptographic APIs, and persists all data via the `kvstore` trait. The design ensures all sensitive material is encrypted at rest and is portable across native and browser environments.

**Core Components:**
- **Vault:** Main manager for encrypted keyspace and cryptographic operations.
- **KeyPair:** Represents individual asymmetric keypairs (e.g., secp256k1, Ed25519).
- **Symmetric Encryption Module:** Handles encryption/decryption and key derivation.
- **SessionManager (Optional):** Maintains current context (e.g., selected keypair) for user sessions.
- **KVStore:** Async trait for backend-agnostic persistence (sled on native, IndexedDB on WASM).



You can design the vault crate to support both stateless and session-based (stateful) usage patterns. This gives maximum flexibility to both library developers and application builders.

### Stateless API
- All operations require explicit context (unlocked keyspace, keypair, etc.) as arguments.
- No hidden or global state; maximally testable and concurrency-friendly.
- Example:
  ```rust
  let keyspace = vault.unlock_keyspace("personal", b"password").await?;
  let signature = keyspace.sign("key1", &msg).await?;
  ```

### Session Manager API
- Maintains in-memory state of unlocked keyspaces and current selections.
- Provides ergonomic methods for interactive apps (CLI, desktop, browser).
- Example:
  ```rust
  let mut session = SessionManager::new();
  session.unlock_keyspace("personal", b"password", &vault)?;
  session.select_keypair("key1");
  let signature = session.current_keypair().unwrap().sign(&msg)?;
  session.logout(); // wipes all secrets from memory
  ```

### How They Work Together
- The **stateless API** is the core, always available and used internally by the session manager.
- The **session manager** is a thin, optional layer that wraps the stateless API for convenience.
- Applications can choose which pattern fits their needs, or even mix both (e.g., use stateless for background jobs, session manager for user sessions).

### Benefits
- **Flexibility:** Library users can pick the best model for their use case.
- **Security:** Session manager can enforce auto-lock, timeouts, and secure memory wiping.
- **Simplicity:** Stateless API is easy to test and reason about, while session manager improves UX for interactive flows.

### Commitment: Provide Both APIs
- **Both stateless and session-based APIs will be provided in the vault crate.**
- Stateless API: For backend, automation, or library contexts—explicit, functional, and concurrency-friendly.
- Session manager API: For UI/UX-focused applications—ergonomic, stateful, and user-friendly.

---

## Data Model

### VaultMetadata & Keyspace Model
```rust
struct VaultMetadata {
    name: String,
    keyspaces: Vec<KeyspaceMetadata>,
    // ... other vault-level metadata (optionally encrypted)
}

struct KeyspaceMetadata {
    name: String,
    salt: [u8; 16], // Unique salt for this keyspace
    encrypted_blob: Vec<u8>, // All keypairs & secrets, encrypted with keyspace password
    // ... other keyspace metadata
}

// The decrypted contents of a keyspace:
struct KeyspaceData {
    keypairs: Vec<KeyEntry>,
    // ... other keyspace-level metadata
}

struct KeyEntry {
    id: String,
    key_type: KeyType,
    private_key: Vec<u8>, // Only present in memory after decryption
    public_key: Vec<u8>,
    metadata: Option<KeyMetadata>,
}

enum KeyType {
    Secp256k1,
    Ed25519,
    // ...
}
```

- The vault contains a list of keyspaces, each with its own salt and encrypted blob.
- Each keyspace is unlocked independently using its password and salt.
- Key material is never stored unencrypted; only decrypted in memory after unlocking a keyspace.

---

## 3. API Design (Keyspace Model)

### Vault
```rust
impl<S: KVStore + Send + Sync> Vault<S> {
    async fn open(store: S) -> Result<Self, VaultError>;
    async fn list_keyspaces(&self) -> Result<Vec<KeyspaceInfo>, VaultError>;
    async fn create_keyspace(&mut self, name: &str, password: &[u8]) -> Result<(), VaultError>;
    async fn delete_keyspace(&mut self, name: &str) -> Result<(), VaultError>;
    async fn unlock_keyspace(&mut self, name: &str, password: &[u8]) -> Result<(), VaultError>;
    async fn lock_keyspace(&mut self, name: &str);
    // ...
}
```

### Keyspace Management
```rust
impl Keyspace {
    fn is_unlocked(&self) -> bool;
    fn name(&self) -> &str;
    async fn create_key(&mut self, key_type: KeyType, name: &str) -> Result<String, VaultError>;
    async fn list_keys(&self) -> Result<Vec<KeyInfo>, VaultError>;
    async fn sign(&self, key_id: &str, msg: &[u8]) -> Result<Signature, VaultError>;
    async fn encrypt(&self, key_id: &str, plaintext: &[u8]) -> Result<Ciphertext, VaultError>;
    async fn decrypt(&self, key_id: &str, ciphertext: &[u8]) -> Result<Vec<u8>, VaultError>;
    async fn change_password(&mut self, old: &[u8], new: &[u8]) -> Result<(), VaultError>;
    // ...
}
```

### SessionManager
```rust
impl SessionManager {
    fn select_key(&mut self, key_id: &str);
    fn current_key(&self) -> Option<&KeyPair>;
}
```


```
vault/
├── src/
│   ├── lib.rs            # Vault API and main logic
│   ├── data.rs           # Data models: VaultData, KeyEntry, etc.
│   ├── crypto.rs         # Symmetric/asymmetric crypto, key derivation
│   ├── session.rs        # SessionManager
│   ├── error.rs          # VaultError and error handling
│   └── utils.rs          # Helpers, serialization, etc.
├── tests/
│   ├── native.rs         # Native (sled) tests
│   └── wasm.rs           # WASM (IndexedDB) tests
└── ...
```

---

## Advanced Notes

- For further context on cryptographic choices, async patterns, and WASM compatibility, see `architecture.md`.
- This appendix is intended for developers extending or maintaining the Vault implementation.

### Cryptography: Crates and Algorithms

**Crates:**
- [`aes-gcm`](https://crates.io/crates/aes-gcm): AES-GCM authenticated encryption (WASM-compatible)
- [`chacha20poly1305`](https://crates.io/crates/chacha20poly1305): ChaCha20Poly1305 authenticated encryption (WASM-compatible)
- [`pbkdf2`](https://crates.io/crates/pbkdf2): Password-based key derivation (WASM-compatible)
- [`scrypt`](https://crates.io/crates/scrypt): Alternative KDF, strong and WASM-compatible
- [`k256`](https://crates.io/crates/k256): secp256k1 ECDSA (Ethereum keys)
- [`ed25519-dalek`](https://crates.io/crates/ed25519-dalek): Ed25519 keypairs
- [`rand_core`](https://crates.io/crates/rand_core): Randomness, WASM-compatible
- [`getrandom`](https://crates.io/crates/getrandom): Platform-agnostic RNG

**Algorithm Choices:**
- **Vault Encryption:**
  - AES-256-GCM (default, via `aes-gcm`)
  - Optionally ChaCha20Poly1305 (via `chacha20poly1305`)
- **Password Key Derivation:**
  - PBKDF2-HMAC-SHA256 (via `pbkdf2`)
  - Optionally scrypt (via `scrypt`)
- **Asymmetric Keypairs:**
  - secp256k1 (via `k256`) for Ethereum/EVM
  - Ed25519 (via `ed25519-dalek`) for general-purpose signatures
- **Randomness:**
  - Use `rand_core` and `getrandom` for secure RNG in both native and WASM

**Feature-to-Algorithm Mapping:**
| Feature                | Crate(s)              | Algorithm(s)              |
|------------------------|-----------------------|---------------------------|
| Vault encryption       | aes-gcm, chacha20poly1305 | AES-256-GCM, ChaCha20Poly1305 |
| Password KDF           | pbkdf2, scrypt        | PBKDF2-HMAC-SHA256, scrypt|
| Symmetric encryption   | aes-gcm, chacha20poly1305 | AES-256-GCM, ChaCha20Poly1305 |
| secp256k1 keypairs     | k256                  | secp256k1 ECDSA           |
| Ed25519 keypairs       | ed25519-dalek         | Ed25519                   |
| Randomness             | rand_core, getrandom  | OS RNG                    |

---

## 7. WASM & Native Considerations
- Use only WASM-compatible crypto crates (`aes-gcm`, `chacha20poly1305`, `k256`, `ed25519-dalek`, etc).
- Use `wasm-bindgen`/`wasm-bindgen-futures` for browser interop.
- Use `tokio::task::spawn_blocking` for blocking crypto on native.
- All APIs are async and runtime-agnostic.

---

## 6. Future Extensions
- Multi-user vaults (multi-password, access control)
- Hardware-backed key storage (YubiKey, WebAuthn)
- Key rotation and auditing
- Pluggable crypto algorithms
- Advanced metadata and tagging

---

## 7. References
- See `docs/Architecture.md` and `docs/kvstore-vault-architecture.md` for high-level design and rationale.
- Crypto patterns inspired by industry best practices (e.g., Wire, Signal, Bitwarden).
