# Holecard
Secure CLI password manager with dual-key encryption.
## Features
- **Dual-key encryption**: Master password + secret key for enhanced security
- **Strong cryptography**: Argon2id key derivation + AES-256-GCM encryption
- **System keyring integration**: Secret key stored securely in OS keyring
- **Biometric authentication**: Touch ID, Face ID, Apple Watch, Passkey support on macOS 🆕
- **Session caching**: Avoid repeated password entry with configurable timeout
- **Flexible entries**: Custom key-value fields per entry
- **SSH key management**: Store and manage SSH keys with ssh-agent integration
- **SSH wrapper**: Auto-load keys and connect with aliases (`hc ssh connect git@github.com`)
- **File loading**: Load fields directly from files with `--file` option
- **TOTP support**: Dedicated TOTP entry for 2FA code generation with auto-clipboard copy
- **Smart clipboard**: Copy specific fields with auto-clear after 30 seconds
- **Template injection**: Render templates with entry fields
- **Environment variables**: Run commands with secrets as env vars
- **Vault reinitialization**: Safe vault reset with confirmation prompt
## Installation
### From source (recommended)
```bash
git clone https://github.com/shabarba/holecard
cd holecard
cargo build --release
cp target/release/hc /usr/local/bin/ # or ~/.local/bin/
```
### From crates.io
```bash
cargo install holecard-cli
```
### From binary releases (coming soon)
Download pre-built binaries from [GitHub Releases](https://github.com/shabarba/holecard/releases).
**Supported platforms:**
- macOS Apple Silicon (aarch64)
- macOS Intel (x86_64)
- Linux x86_64
### With Homebrew (coming soon)
```bash
brew tap shabarba/tap
brew install hc
```
### With cargo-binstall (coming soon)
```bash
cargo binstall holecard-cli
```
## Quick Start
```bash
# Initialize vault (creates master password + secret key + totp entry)
hc init
# Add an entry
hc add github -f username=myuser -f password=mypass
# Or add interactively
hc add
# Add SSH key from file
hc add github-key --file private_key=~/.ssh/id_ed25519 -f alias="git@github.com"
# Connect via SSH (auto-loads key)
hc ssh connect git@github.com
# List entries
hc list
# Get an entry
hc get github
# Copy password to clipboard (auto-clears after 30s)
hc get github -c
# Copy specific field
hc get github -c username
# Add TOTP secret
hc totp add github JBSWY3DPEHPK3PXP
# Get TOTP code (displays + copies to clipboard)
hc totp get github
```
## Usage
### Managing Entries
```bash
# Add entry with custom fields
hc add aws -f access_key=AKIA... -f secret_key=...
# Add entry with fields from files
hc add github-key \
--file private_key=~/.ssh/id_ed25519 \
--file public_key=~/.ssh/id_ed25519.pub \
-f alias="git@github.com"
# Edit existing entry
hc edit github -f password=newpass
# Edit with file field
hc edit github-key --file private_key=~/.ssh/id_rsa
# Remove entry
hc rm github
# Copy specific field to clipboard
hc get github -c password # Copy password field
hc get github -c username # Copy username field
hc get github -c # Copy password field (or first field if no password)
# Export vault to JSON (plaintext - handle with care)
hc export backup.json
# Import from JSON
hc import backup.json
hc import backup.json --overwrite # Replace existing entries
```
### SSH Key Management
Securely store SSH keys and manage ssh-agent with seamless integration.
```bash
# Add SSH key from file (recommended - preserves newlines)
hc add my-server \
--file private_key=~/.ssh/id_rsa \
-f alias="user@server.com,prod" \
-f passphrase="optional"
# Connect via SSH (auto-loads key)
hc ssh connect user@server.com
hc ssh connect prod
hc ssh connect my-server
# Pass additional SSH arguments
hc ssh connect prod -- -p 2222 -v
# Manually load key into ssh-agent
hc ssh load my-server
# Load with lifetime (auto-expires after 8 hours)
hc ssh load my-server --lifetime 28800
# List loaded keys in ssh-agent
hc ssh list
# Unload key from ssh-agent
hc ssh unload my-server
```
**Why use `hc ssh` over plain `ssh-add`?**
- Store encrypted SSH keys in vault with Argon2id + AES-256-GCM
- Auto-load keys on connect with aliases (`git@github.com` → Entry name)
- Manage passphrases securely without typing them repeatedly
- Integrate with session management (`hc lock` clears both vault and ssh-agent)
### TOTP Support
All TOTP secrets are stored in a dedicated `totp` entry that is automatically created during initialization.
```bash
# Add TOTP secret for a service
hc totp add github JBSWY3DPEHPK3PXP
hc totp add aws KBSWY3DPEHPK3PXQ
# Get TOTP code (displays + copies to clipboard)
hc totp get github
# Output:
# TOTP Code: 123456 (valid for 28 seconds)
# ✓ Copied to clipboard (will clear in 30 seconds)
# Remove TOTP secret
hc totp rm github
# View all TOTP services
hc get totp
```
### Template Injection
```bash
# Render template with entry fields
hc inject github "https://{{username}}:{{password}}@github.com"
# Access specific fields
hc inject aws "AWS_ACCESS_KEY={{access_key}}"
```
### Running Commands with Secrets
```bash
# Entry fields become uppercase environment variables
# Use with any command
hc run database -- psql -h localhost -U $USERNAME -d mydb
```
### Biometric Authentication (macOS only)
Touch ID, Face ID, Apple Watch, and Passkey authentication for seamless vault access.
```bash
# Enable/disable biometric authentication (enabled by default on macOS)
hc config enable-biometric true
# First unlock: Biometric + master password entry (cached in keyring)
# Subsequent unlocks: Biometric only (no password needed)
# Biometric authentication required for sensitive operations:
# - hc get --show/--clip
# - hc edit
# - hc rm
# - hc export
```
**Supported authentication methods:**
- Touch ID (MacBook Pro/Air, Magic Keyboard)
- Face ID (future Mac devices)
- Apple Watch unlock
- Passkey
- macOS login password (fallback)
### Session Management
```bash
# Check session status
hc status
# Lock vault (clear cached session)
hc lock
# Configure session timeout (minutes)
hc config session-timeout 30
```
### Configuration
```bash
# View current config
hc config
# Set vault file path
hc config vault-path ~/Dropbox/vault.enc
# Set session timeout
hc config session-timeout 120
# Reinitialize vault (WARNING: deletes all data)
hc init
# Output:
# âš Vault already exists!
# âš Vault already exists. Reinitialize? This will DELETE ALL existing data! (y/N):
```
## Security
### Encryption
- **Key derivation**: Argon2id with master password + secret key
- **Encryption**: AES-256-GCM with random nonce per save
- **Secret key**: 160-bit random key stored in system keyring
### Backup and Recovery
Use `hc export` to backup your entire vault:
```bash
hc export backup.json
```
The export file is encrypted with a password you choose. To restore:
```bash
hc import backup.json
```
**Important**:
- Store export files in a secure location (external drive, encrypted cloud storage, etc.)
- Use a strong password for export encryption
- You need BOTH the export file and its password to restore your vault
- Regular backups protect against data loss
### Session Caching
The derived encryption key is cached in the system keyring to avoid repeated password entry. Sessions automatically expire after the configured timeout (default: 60 minutes).
### Biometric Authentication (macOS)
On macOS, biometric authentication is enabled by default. After the initial setup:
1. **First unlock**: Touch ID/Face ID + master password entry (password cached in keyring)
2. **Subsequent unlocks**: Touch ID/Face ID only (password retrieved automatically)
Sensitive operations (`get --show`, `edit`, `rm`, `export`) require additional biometric verification for security.
**Security benefits:**
- No password typing (reduces shoulder surfing risk)
- Master password stored in macOS keyring with device-level encryption
- Biometric authentication uses system LocalAuthentication framework
- Automatic fallback to password if biometric unavailable
## File Locations
| `~/.holecard/config.toml` | Configuration file (`enable_biometric`, `vault_path`, `session_timeout_minutes`) |
| `~/.holecard/vault.enc` | Encrypted vault (default) |
| `~/.holecard/session_*.json` | Session metadata |
| macOS Keychain | Master password (when biometric enabled), secret key, session key |
## Platform Support
- **macOS**: Apple Silicon (aarch64) and Intel (x86_64)
- **Linux**: x86_64 GNU
## Building from Source
```bash
# Clone repository
git clone https://github.com/shabarba/holecard
cd holecard
# Build
cargo build --release
# Run tests
cargo test
# Check
cargo check
# Lint
cargo clippy
# Format
cargo fmt
# Install locally
cargo install --path .
```
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
## Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
## Acknowledgments
Built with:
- [clap](https://github.com/clap-rs/clap) - Command line argument parsing
- [argon2](https://github.com/RustCrypto/password-hashes) - Key derivation
- [aes-gcm](https://github.com/RustCrypto/AEADs) - Authenticated encryption
- [keyring](https://github.com/hwchen/keyring-rs) - System keyring access
- [security-framework](https://github.com/kornelski/rust-security-framework) - macOS keychain integration (macOS)
- [totp-lite](https://github.com/fosskers/totp-lite) - TOTP implementation
- [sha2](https://github.com/RustCrypto/hashes) - SSH key fingerprint calculation
- [tempfile](https://github.com/Stebalien/tempfile) - Secure temporary file handling