Overview
Fishnet stores all API credentials in an encrypted SQLite vault. Regular backups ensure you can recover your credentials in case of:
- Hardware failure
- Accidental deletion
- Migration to a new machine
- Vault corruption
Backups contain your encrypted credentials. While they are encrypted with your master password, store backup files securely.
Vault Location
The vault database is stored in the Fishnet data directory:
~/Library/Application Support/Fishnet/vault.db
~/.local/share/fishnet/vault.db
The vault file is protected with mode 0600 (owner read/write only).
Creating Backups
Automatic Backup Path
By default, backups are saved with a timestamp:
Example output:
Backup written to ~/.local/share/fishnet/backups/vault-20260303-143022.db.bak
Custom Backup Path
Specify a custom output location:
fishnet backup --output ~/my-backups/fishnet-vault-$(date +%Y%m%d).db.bak
Backup Directory Structure
Default backups are organized by timestamp:
~/.local/share/fishnet/backups/
├── vault-20260301-100000.db.bak
├── vault-20260302-100000.db.bak
└── vault-20260303-143022.db.bak
Backup files are exact copies of the encrypted vault. They do NOT contain plaintext credentials.
Restoring from Backup
Prerequisites
Stop Fishnet
The restore command checks if Fishnet is running and refuses to proceed if detected. Locate your backup file
ls -lh ~/.local/share/fishnet/backups/
Restore Command
fishnet restore /path/to/vault-backup.db.bak
You’ll be prompted for confirmation:
Restore vault from '/path/to/vault-backup.db.bak' and overwrite current vault? [y/N]
Skip Confirmation
For scripted restores:
fishnet restore /path/to/vault-backup.db.bak --yes
Restoring a backup will completely replace your current vault. Any credentials added since the backup was created will be lost.
Backup Strategies
Manual Backups
Create a backup before risky operations:
# Before bulk credential changes
fishnet backup --output ~/safe-vault-backup.db.bak
# Make changes
fishnet add-key --service openai --name prod-key --key sk-...
fishnet remove-key old-key
# If something goes wrong:
fishnet stop
fishnet restore ~/safe-vault-backup.db.bak --yes
fishnet start
Automated Backups
Use cron (Linux) or launchd (macOS) to schedule regular backups:
Linux (cron)
macOS (launchd)
Edit your crontab:Add a daily backup at 2 AM:0 2 * * * /usr/local/bin/fishnet backup --output ~/fishnet-backups/vault-$(date +\%Y\%m\%d).db.bak
Create ~/Library/LaunchAgents/local.fishnet.backup.plist:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.fishnet.backup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/fishnet</string>
<string>backup</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
Load the agent:launchctl load ~/Library/LaunchAgents/local.fishnet.backup.plist
Remote Backups
Sync backups to cloud storage or remote servers:
# Backup to restic repository
fishnet backup --output /tmp/fishnet-vault.db.bak
restic -r /srv/restic-repo backup /tmp/fishnet-vault.db.bak
rm /tmp/fishnet-vault.db.bak
Backup Retention
Manage backup storage by cleaning up old backups:
# Keep last 30 days
find ~/.local/share/fishnet/backups/ -name "vault-*.db.bak" -mtime +30 -delete
# Keep last 10 backups
ls -t ~/.local/share/fishnet/backups/vault-*.db.bak | tail -n +11 | xargs rm -f
Fishnet does not automatically delete old backups. Implement your own retention policy based on your recovery requirements.
Verifying Backups
Test that a backup can be restored:
Create a test environment
mkdir /tmp/fishnet-test
export XDG_DATA_HOME=/tmp/fishnet-test
Initialize with a test password
fishnet init --master-password testpass123 \
--first-service test --first-name test --first-key test-key \
--daily-budget-usd 1.0 --rate-limit-per-minute 10
Restore the backup
fishnet restore ~/path/to/backup.db.bak --yes
Cleanup
unset XDG_DATA_HOME
rm -rf /tmp/fishnet-test
Disaster Recovery
Vault Corruption
If your vault becomes corrupted:
# Check vault integrity
sqlite3 ~/.local/share/fishnet/vault.db "PRAGMA integrity_check;"
# If corrupted, restore from backup
fishnet stop
fishnet restore ~/.local/share/fishnet/backups/vault-LATEST.db.bak --yes
fishnet start
Migration to New Machine
On old machine: Create backup
fishnet backup --output ~/fishnet-migration.db.bak
Transfer backup file
scp ~/fishnet-migration.db.bak user@new-machine:~/
On new machine: Install Fishnet
# Install fishnet binary
# Then initialize (creates data directory structure)
fishnet init
Restore from backup
fishnet stop
fishnet restore ~/fishnet-migration.db.bak --yes
fishnet start
Verify
fishnet list-keys
fishnet status
Lost Master Password
If you lose your master password, encrypted vault backups cannot be recovered. The encryption is designed to be unrecoverable without the password.
Preventive measures:
- Store your master password in a password manager
- Use the keychain integration (macOS):
fishnet init --store-derived-key-in-keychain
- Document your recovery procedure
- Test restoration process regularly
Backup File Security
Encryption Details
Backup files are encrypted SQLite databases using:
- Algorithm: AES-256-GCM
- Key derivation: Argon2id (from master password)
- Per-credential encryption: Unique nonces
Storage Recommendations
✅ Do:
- Store backups on encrypted filesystems
- Use restrictive file permissions (600)
- Keep backups offline or air-gapped
- Test restoration quarterly
❌ Don’t:
- Store backups in public cloud storage without additional encryption
- Email backup files
- Store backups on the same physical drive as the original vault
- Share backups unencrypted
Backup Size
Vault backup size depends on credential count:
- Empty vault: ~20 KB
- 10 credentials: ~24 KB
- 100 credentials: ~40 KB
- 1000 credentials: ~200 KB
Backups are lightweight and compress well with gzip/bzip2.