A secure, file-based password manager with hierarchical organization. Written in Rust for performance and security.
- 🔐 Per-item encryption with Argon2id + AES-256-GCM
- 📁 Hierarchical organization of secrets
- 📝 TOML-based vault format for easy editing and versioning
- 🔍 Fast filtering of entries
- 📋 Clipboard integration with automatic clearing
- 🚀 Interactive and CLI modes
- 🦀 Written in Rust for performance and security
- 📦 Easy installation via npm or pre-built binaries
- 🔑 GPG integration for additional vault encryption
- 💾 Automatic backups when modifying vault files
- 🛡️ Overwrite protection with user prompts
# Install globally
npm install -g @lucklyric/vaultify
# Or with yarn
yarn global add @lucklyric/vaultify
# Or run directly with npx
npx @lucklyric/vaultify
Download the latest release for your platform from the releases page.
# Clone the repository
git clone https://github.com/Lucklyric/vaultify.git
cd vaultify
# Build with Rust
cargo build --release
# Binary will be at target/release/vaultify
vaultify init
This creates a vault.toml
file in the current directory.
# Will open your system editor for secure input
vaultify add personal/email/gmail -d "Personal Gmail account"
# From stdin
echo "my-secret-password" | vaultify add personal/email/gmail --stdin -d "Personal Gmail"
# Simple list
vaultify list
# Tree view
vaultify list --tree
# Filter by scope
vaultify list personal/email
# Interactive mode - choose display format after entering password
vaultify decrypt personal/email/gmail
# Show in terminal directly
vaultify decrypt personal/email/gmail --show
# Direct to clipboard (auto-clears after 60 seconds)
vaultify decrypt personal/email/gmail --no-display --clipboard
vaultify edit personal/email/gmail
vaultify delete personal/email/gmail
# Encrypt entire vault with GPG (prompts for backup and ASCII armor)
vaultify gpg-encrypt --recipient user@example.com
# Symmetric encryption (password-based)
vaultify gpg-encrypt
# Create ASCII-armored output (.asc)
vaultify gpg-encrypt --armor
# Decrypt GPG-encrypted vault
vaultify gpg-decrypt
Run vaultify
without any arguments to enter interactive mode:
vaultify
vaultify> help
vaultify> list
vaultify> add work/vpn
vaultify> decrypt work/vpn
vaultify> exit
Vaults are stored as TOML files with encrypted content:
version = "v0.3.1"
modified = "2025-01-17T10:00:00Z"
[personal]
description = "Personal accounts"
encrypted = ""
salt = ""
[personal.email]
description = "Email accounts"
encrypted = "base64-encoded-encrypted-content"
salt = "base64-encoded-salt"
- Insertion order preserved: Entries maintain their original order
- Smart group insertion: New entries are added at the end of their group
- Native TOML format: Clean, readable structure with dotted key notation
- Flexible parsing: Parent entries are created automatically
Vaultify automatically creates timestamped backups when modifying vault files:
- Vault modifications: Prompts to create backup (default: Yes)
- GPG encryption: Prompts to create backup (default: Yes)
- Backup format:
vault.toml.backup.20250721_152607
- GPG backup format:
vault.toml.gpg.backup.20250721_152607
- Prompts before overwriting existing files
- Applies to backups, GPG encryption, and GPG decryption
- Prevents accidental data loss
- Encryption: Each entry is encrypted with Argon2id + AES-256-GCM
- Per-item salts: Every entry has its own salt for enhanced security
- Memory safety: Written in Rust with automatic memory zeroing
- No password storage: Password required for every operation
- Secure permissions: Vault files are created with 600 permissions
- Backup protection: Automatic backups prevent data loss
VAULT_FILE
: Default vault file pathEDITOR
orVISUAL
: System editor for secret input (defaults: notepad on Windows, vi on Unix)
On Unix systems, vault files are automatically created with 600 permissions (read/write for owner only).
This section provides a detailed technical specification of the encryption algorithms used by vaultify. This information allows anyone to implement a compatible decryption tool in any programming language.
Each secret in the vault is independently encrypted using:
- Key Derivation: Argon2id
- Encryption: AES-256-GCM
- Encoding: Base64 for storage
Parameters:
- Memory: 65536 KB (64 MB)
- Iterations: 2
- Parallelism: 1
- Salt length: 16 bytes (128 bits)
- Key length: 32 bytes (256 bits)
Parameters:
- Key: 32 bytes from Argon2id
- Nonce: 12 bytes (96 bits) - randomly generated
- Additional Authenticated Data (AAD): None
- Tag length: 16 bytes (128 bits)
Each encrypted entry in the TOML file contains:
encrypted
: Base64-encoded concatenation of [nonce || ciphertext || tag]salt
: Base64-encoded 16-byte salt used for Argon2id
To decrypt an entry:
- Parse the TOML file and extract the target entry's
encrypted
andsalt
fields - Decode from Base64 both fields
- Extract components from the encrypted data:
- Nonce: First 12 bytes
- Ciphertext: Bytes 12 to (length - 16)
- Tag: Last 16 bytes
- Derive key using Argon2id with the decoded salt and user's password
- Decrypt using AES-256-GCM with the derived key, nonce, and tag
- Verify the authentication tag - decryption fails if tag is invalid
import base64
from argon2 import low_level
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def decrypt_vault_entry(encrypted_b64, salt_b64, password):
# Decode from base64
encrypted = base64.b64decode(encrypted_b64)
salt = base64.b64decode(salt_b64)
# Extract components
nonce = encrypted[:12]
ciphertext_with_tag = encrypted[12:]
# Derive key using Argon2id
key = low_level.hash_secret_raw(
secret=password.encode(),
salt=salt,
time_cost=2,
memory_cost=65536,
parallelism=1,
hash_len=32,
type=low_level.Type.ID
)
# Decrypt using AES-256-GCM
aesgcm = AESGCM(key)
plaintext = aesgcm.decrypt(nonce, ciphertext_with_tag, None)
return plaintext.decode('utf-8')
- Per-entry encryption: Each secret has its own salt and encryption
- No master key: There's no vault-wide master password
- Forward secrecy: Compromising one entry doesn't affect others
- Authentication: GCM mode provides both encryption and authentication
- Memory hardness: Argon2id resists GPU/ASIC attacks
cargo build --release
cargo test
# Format code
cargo fmt
# Run linter
cargo clippy
Contributions are welcome! Please read our Contributing Guide for details.
Licensed under the Apache License 2.0. See LICENSE for details.