Hana Vault Format
A secure, production-ready Rust library for storing SSH credentials, hosts, and sensitive data using an encrypted SQLite vault format.
Features
- In-Memory SQLite Storage - Database lives in RAM and is never written to disk in plaintext
- Binary Encryption - Export/import vaults as encrypted bytes (perfect for network transmission)
- Autonomous Migrations - Schema versioning with automatic migration system
- Multiple Auth Types - Support for username/password, RSA, OpenSSH, Ed25519, ECDSA, and certificate-based authentication
- Host Management - Store hosts with startup commands, environment variables, and custom encodings
- Industry-Standard Crypto - AES-256-GCM symmetric encryption
- Key-Based API - Supply your own 256-bit key (derive from password in your application)
- Zero Plaintext - Raw SQLite database never exposed - only encrypted formats allowed
- Memory Safety - Sensitive data automatically zeroized on drop
Security Features
Multi-Layer Security
-
In-Memory SQLite Database
- Database exists only in RAM, never on disk
- Isolated from filesystem exposure
- Automatic cleanup on process termination
-
Binary Format Encryption
- AES-256-GCM for authenticated encryption
- Key-based API (derive keys using Argon2id in your application)
- SHA-256 checksums for integrity verification
- Random nonce for each encryption operation
-
Security Best Practices
- No plaintext SQLite ever written to disk
- In-memory database only
- Zeroization of sensitive data
- Foreign key constraints for data integrity
- Prepared statements to prevent SQL injection
Quick Start
use ;
Key Derivation
This library accepts a raw 256-bit key. In your application, derive it from a user password using Argon2id:
use ;
use ;
Usage Examples
Loading Vaults
use ;
// Load from encrypted file
let encrypted_bytes = read?;
let key = derive_key; // Your key derivation
let vault = load_from_bytes?;
Reading Vault ID
You can read the unique identifier of a vault without decrypting it (useful for system keyrings):
use Vault;
let encrypted_bytes = read?;
let vault_id = get_id_from_bytes?;
println!;
Managing Hosts
use Host;
// Create a host
let mut host = new;
// Add startup command
host = host.with_startup_command;
// Set custom encoding
host = host.with_encoding;
// Add environment variables
host.add_env_var;
host.add_env_var;
vault.add_host?;
// List all hosts
let hosts = vault.list_hosts?;
// Get specific host
let host = vault.get_host?;
// Update host
host.port = 2222;
vault.update_host?;
// Delete host
vault.delete_host?;
Managing Credentials
use ;
// Username/Password credentials
let cred = new_username_password;
vault.add_credential?;
// RSA key credentials
let rsa_cred = new_ssh_key;
vault.add_credential?;
// Ed25519 key credentials
let ed25519_cred = new_ssh_key;
vault.add_credential?;
// List all credentials
let credentials = vault.list_credentials?;
// Update credential
cred.name = "Updated Name".to_string;
vault.update_credential?;
// Delete credential
vault.delete_credential?;
Linking Credentials to Hosts
// Link a credential to a host (set as default)
vault.link_credential_to_host?;
// Link another credential to the same host (not default)
vault.link_credential_to_host?;
// Get all credentials for a host
let host_creds = vault.get_host_credentials?;
for in host_creds
// Unlink credential from host
vault.unlink_credential_from_host?;
Database Schema
The library uses an SQLite database with the following schema:
hosts- Host configurations (hostname, port, startup commands, encoding, etc.)host_env_vars- Environment variables for hostscredentials- Authentication credentials (all types)host_credentials- Many-to-many relationship between hosts and credentialsschema_version- Automatic migration tracking
Versioning & Migrations
The library includes an autonomous migration system that:
- Automatically detects schema version on vault load
- Runs pending migrations seamlessly
- Ensures backward compatibility
- Tracks applied migrations
Migrations run automatically when you load a vault, ensuring it's always at the latest schema version.
KDF Compatibility
Vaults encrypted with one key-derivation configuration are not guaranteed to be decryptable by builds that change the KDF parameters/algorithm. If you need to support older vault files, keep the previous KDF available for decryption and migrate by re-exporting.
Testing
Run the comprehensive test suite:
Run tests with output:
API Reference
Core Types
-
Vault- Main vault structure for managing encrypted datanew(key)- Create new vault with encryption keyload_from_bytes(bytes, key)- Load from encrypted bytesexport_to_bytes()- Export as encrypted bytesget_id_from_bytes(bytes)- Get vault ID without decrypting
-
SecretKey- 256-bit encryption keyrandom()- Generate a random keyfrom_bytes(bytes)- Create from raw bytes (e.g., after KDF)
-
Host- Host configurationnew(name, hostname, port)- Create new hostwith_startup_command(cmd)- Set startup commandwith_encoding(encoding)- Set custom encodingadd_env_var(key, value)- Add environment variable
-
Credential- Authentication credentialnew_username_password(name, username, password)- Create password credentialnew_ssh_key(name, type, private_key, public_key, passphrase)- Create SSH key credential
-
CredentialType- Enum of supported authentication typesUsernamePasswordRsaOpenSshEd25519EcdsaCertificateCustom
Error Handling
All operations return Result<T, VaultError>:
use ;
let bytes = read?;
let key = random; // Your derived key
match load_from_bytes
File Format
Encrypted vault files (.hev) have the following structure:
┌─────────────────────────────────────────┐
│ Header (68 bytes, unencrypted) │
│ ├─ Magic bytes (8 bytes): "HANAVLT1" │
│ ├─ Version (4 bytes): u32 │
│ ├─ UID (16 bytes): UUID v4 │
│ ├─ Checksum (32 bytes): SHA-256 │
│ └─ Data size (8 bytes): u64 │
├─────────────────────────────────────────┤
│ Encrypted Data │
│ ├─ Nonce (12 bytes) │
│ └─ Ciphertext (variable) │
│ └─ Encrypted SQLite database │
└─────────────────────────────────────────┘
Contributing
Contributions are welcome! Please ensure:
- All tests pass (
cargo test) - Code follows Rust conventions (
cargo fmt,cargo clippy) - Security implications are considered
- Documentation is updated
License
This project is licensed under the MIT License - see the LICENSE file for details.