A secure GPG-based password manager for the Fish shell.
- Store passwords securely using GPG encryption
- Generate secure random passwords
- Copy passwords to clipboard without displaying them
- List all stored passwords in a beautiful table format
- Import/export functionality for backups
- Import passwords from the standard pass utility
- Tab completion for all commands
- Store and retrieve usernames and URLs alongside passwords
Install with Fisher:
fisher install akarsh1995/fish-pwstore- Fish shell (3.0.0+)
- GPG for encryption
- jq for JSON processing
- Optional: pass for importing existing passwords
The password store is accessed through the pw command:
pw COMMAND [ARGS...]pw add NAME [--username=VALUE] [--url=VALUE] [DESC]- Add/update a password (will prompt for password)pw gen NAME [LENGTH] [--username=VALUE] [--url=VALUE] [DESC]- Generate and store a passwordpw get NAME- Copy password to clipboardpw show NAME- Show password in terminalpw user NAME- Copy username/email to clipboardpw url NAME- Copy URL to clipboardpw desc NAME- Copy description to clipboardpw lsorpw list- List all stored passwords in a formatted tablepw rm NAME- Delete a passwordpw export PATH- Export passwords to a filepw import PATH- Import passwords from a filepw import-pass [DIR] [--verbose]- Import passwords from standard passpw init- Initialize the password storepw help- Show help message
Add a password (will prompt for password):
pw add github "GitHub account password"Add a password with username (will prompt for password):
pw add github --username=user@example.com "GitHub account password"Add a password with username and URL (will prompt for password):
pw add github --username=user@example.com --url=https://github.com "GitHub account password"Get a password description:
pw desc githubGenerate a random password:
pw gen netflix 16 "Netflix account password"Generate a random password with username:
pw gen netflix 16 --username=user@example.com "Netflix account password"Generate a random password with username and URL:
pw gen netflix 16 --username=user@example.com --url=https://netflix.com "Netflix account password"Retrieve a password (copies to clipboard):
pw get githubDisplay a password in the terminal:
pw show githubCopy the username/email to clipboard:
pw user githubCopy the URL to clipboard:
pw url githubList all stored passwords in a formatted table:
pw lsShow additional details including update timestamps:
pw ls --detailsDelete a password:
pw rm githubExport passwords for backup:
pw export ~/backup/passwords.gpgImport passwords:
pw import ~/backup/passwords.gpgImport from standard pass password manager:
# Import from default pass location (~/.password-store)
pw import-pass
# Import from a specific pass directory
pw import-pass /path/to/password-store
# Import with verbose output
pw import-pass --verboseSee PASS_IMPORT_GUIDE.md for detailed instructions on importing from pass, including handling nested directories and troubleshooting.
You can customize pwstore behavior by setting these variables in your config.fish:
# Change the password storage location
set -U pwstore_path $HOME/.password-store
# Change the default generated password length (default: 20)
set -U pwstore_password_length 24
# Set a specific GPG recipient (default: first available key or current user)
# Format can be name, email, or key ID
set -U pwstore_gpg_recipient "Your Name <your.email@example.com>"
# Or use a specific key ID (recommended for more reliable operation)
# set -U pwstore_gpg_recipient "0xA1B2C3D4E5F6G7H8"- All passwords are encrypted using GPG with your personal key
- Passwords are never stored in plain text on disk
- When copying to clipboard, passwords are not displayed on screen
- Passwords are entered via masked prompts to prevent terminal history leakage
- All sensitive operations require GPG decryption
- Clipboard contents remain until manually cleared or overwritten
By default, passwords are stored in:
$XDG_CONFIG_HOME/fish/secure/passwords/registry.json.gpg
You can change this location by setting the pwstore_path variable.
If you encounter GPG-related issues such as "Failed to save the password registry" or other encryption problems:
-
Run the included diagnostic script:
./debug_pwstore_gpg.fish
This will provide detailed information about your GPG setup and potential issues.
-
Create a GPG key if you don't have one:
gpg --gen-keyFollow the prompts to create a new key pair.
-
Set a specific GPG recipient using your key ID:
set -U pwstore_gpg_recipient "YOUR_KEY_ID"
You can find your key ID by running
gpg --list-keys. -
Check directory permissions:
ls -la $pwstore_path
Make sure you have write permissions for the directory.
For issues with importing passwords from the standard pass password manager:
-
See the detailed guide:
less PASS_IMPORT_GUIDE.md
-
Run the test suite to verify functionality:
fish ./tests/run_tests.fish
Or run individual test scripts:
fish ./tests/test_realpath_import.fish fish ./tests/test_pass_import_integration.fish
-
Use verbose mode for more information:
pw import-pass --verbose
All Fish files in this project are formatted using fish_indent. We provide several tools to make formatting easier:
-
Format all Fish files in the repository:
./run_fish_indent.fish
-
Check formatting without making changes (useful for CI):
./run_fish_indent.fish --check -
Format only git-staged files:
./run_fish_indent.fish --git -
Use the pre-commit hook to automatically format files before committing:
ln -sf (pwd)/pre-commit.fish .git/hooks/pre-commit
The CI workflow checks that all files are properly formatted. Pull requests with improperly formatted code may be automatically corrected.
- VS Code: We include settings for VS Code in
.vscode/settings.jsonand recommend the fish-ide extension. - Editor Config: An
.editorconfigfile is included to maintain consistent coding styles across different editors.