A secure, self-hosted password manager consisting of:
- Rust backend — single binary, AES-256-GCM encrypted vault, Argon2id key derivation
- Browser extension — Chrome & Firefox (Manifest V3), React UI
- Security Model
- Installation
- Configuration
- Running the Backend
- Loading the Extension
- API Reference
- Backup & Restore
- Development
- Zero-knowledge architecture: the master password is never stored or transmitted. Only its Argon2id-derived key is held in memory while the vault is unlocked.
- AES-256-GCM encryption for the vault file. A fresh 96-bit nonce is generated for every write.
- Argon2id (memory=64 MiB, iterations=3, parallelism=4 by default) for key derivation and password verification.
- HKDF-SHA256 to derive separate encryption and HMAC keys from the Argon2id output.
- JWT (HS256) access tokens (30-minute expiry) and refresh tokens (7-day expiry).
- Automatic locking after configurable inactivity period.
- Rate limiting on failed unlock attempts (5 per minute by default).
- Atomic writes to prevent vault corruption (write → fsync-like → rename).
- Automatic backups before every vault write, with configurable retention.
Download the latest release binary for your platform from the Releases page.
# Prerequisites: Rust stable toolchain
git clone https://github.com/tayyebi/ramz
cd ramz/backend
cargo build --release
# Binary: target/release/ramzCopy backend/config.example.toml to config.toml in your working directory and edit as needed.
Key settings:
| Setting | Default | Description |
|---|---|---|
server.host |
127.0.0.1 |
Bind address |
server.port |
8080 |
Listen port |
security.jwt_secret |
random | JWT signing secret |
security.jwt_expiration_minutes |
30 |
Access token lifetime |
security.inactivity_timeout_minutes |
15 |
Auto-lock timeout |
security.argon2.memory_kib |
65536 |
Argon2id memory (KiB) |
storage.data_dir |
./data |
Vault storage directory |
storage.auto_backup |
true |
Enable automatic backups |
logging.level |
info |
Log verbosity |
Environment variable overrides: RAMZ_HOST, RAMZ_PORT, RAMZ_JWT_SECRET, RAMZ_DATA_DIR, RAMZ_CONFIG (config file path).
# Default (reads config.toml if present, uses defaults otherwise)
./ramz
# Custom config file
RAMZ_CONFIG=/etc/ramz/config.toml ./ramz
# Override settings via environment
RAMZ_PORT=9090 RAMZ_JWT_SECRET=mysecret ./ramzThe first request to POST /api/auth/setup initializes the vault with your master password.
- Build the extension:
cd extension && npm install && npm run build - Open
chrome://extensions - Enable Developer mode
- Click Load unpacked → select the
extension/distfolder
- Open
about:debugging#/runtime/this-firefox - Click Load Temporary Add-on
- Select
extension/dist/manifest.json
For permanent Firefox installation, sign the extension via AMO or use a self-signed XPI.
All protected endpoints require Authorization: Bearer <access_token>.
Error responses follow: {"error": {"code": "CODE", "message": "human-readable message"}}
| Method | Path | Description |
|---|---|---|
GET |
/api/health |
Health check (no auth) |
POST |
/api/auth/setup |
Initialize vault (first time only) |
POST |
/api/auth/unlock |
Unlock vault, returns JWT |
POST |
/api/auth/lock |
Lock vault, invalidate sessions |
POST |
/api/auth/refresh |
Refresh access token |
| Method | Path | Description |
|---|---|---|
GET |
/api/vault/entries |
List entries (supports ?search=, ?sort=, ?order=, ?limit=, ?offset=, ?folder=, ?tag=) |
POST |
/api/vault/entries |
Create entry |
GET |
/api/vault/entries/:id |
Get entry |
PUT |
/api/vault/entries/:id |
Update entry |
DELETE |
/api/vault/entries/:id |
Delete entry |
| Method | Path | Description |
|---|---|---|
GET |
/api/vault/mfa |
List MFA entries |
POST |
/api/vault/mfa |
Create MFA entry |
DELETE |
/api/vault/mfa/:id |
Delete MFA entry |
GET |
/api/vault/mfa/:id/totp |
Get current TOTP code |
POST |
/api/vault/mfa/import |
Import from otpauth:// URI |
| Method | Path | Description |
|---|---|---|
GET |
/api/vault/status |
Vault status |
GET |
/api/vault/export |
Export decrypted vault (JSON) |
POST |
/api/vault/import |
Import vault data |
When storage.auto_backup = true, a timestamped copy of the vault is saved to <data_dir>/backups/vault_YYYYMMDD_HHMMSS.enc before every write. Old backups beyond backup_retention_days are pruned automatically.
cp data/vault.enc vault.enc.backup# Stop the server first
cp vault.enc.backup data/vault.enc
# Restart the server# Backend
cd backend
cargo test # Run all tests
cargo clippy # Lint
cargo fmt # Format
# Extension
cd extension
npm install
npm run build # Production build
npm run dev # Watch mode
npm run lint # TypeScript check