purr is a ZSH plugin that transforms key management from a tedious multi-step process into a single, elegant command. Seamlessly integrate 1Password, SSH, and GPG to securely load keys, configure Git signing, and manage GitHub credentials - all while keeping your workflow fast and secure.
- 🔐 1Password Integration - Store all keys securely in 1Password, no more scattered key files
- 🔑 Automated SSH Management - Connect to 1Password SSH agent with a single command
- 📝 GPG & Git Signing - Automatic GPG key import and Git commit signing configuration
- 🔄 GitHub Credentials - Configure Git user, email, and tokens from 1Password
- 🔒 Secure Lock - Unload all keys and lock 1Password when done (including mcp.json cleanup)
- 🔍 Status Checking - Verify key status, Git signing, and GitHub token configuration
- 🎯 Cursor MCP Ready - Automatically configures GitHub tokens for Cursor MCP servers
- ⚡ Lightning Fast - Get from zero to productive in seconds, not minutes
purr is designed for developers and teams who want a unified, automated solution for managing SSH keys, GPG keys, and Git signing. Perfect for:
- 1Password Users: Developers already using 1Password for credential management who want to leverage it for SSH/GPG keys
- Security-Conscious Teams: Organizations requiring Git commit signing and secure key management practices
- Daily Developers: Developers who want a single command to load all keys and configure their development environment
- Team Leads: Those setting up standardized development environments across team members
- DevOps Engineers: Professionals managing multiple machines who need consistent key management workflows
- macOS Users: Developers on macOS who need seamless integration with system tools and 1Password
- Daily Development Workflow: Load all keys at the start of your day with a single
purrcommand - New Machine Setup: Quickly configure a new development machine with all necessary keys and Git signing
- Team Onboarding: Provide consistent setup instructions for new team members
- Secure Key Rotation: Easily rotate keys stored in 1Password without manual configuration
- Temporary Development Environments: Load keys when needed, lock them when done
- CI/CD Key Management: Future support for automated key management in CI/CD pipelines
- macOS
- ZSH shell
- 1Password CLI (
op) installed and configured - GPG installed (
brew install gnupg) - SSH client (built into macOS)
- lolcat for colorful output (
brew install lolcat)
-
Install 1Password CLI:
brew install --cask 1password-cli
Then authenticate:
op signin -
Install GPG (if not already installed):
brew install gnupg
-
Install lolcat (optional, for colorful output):
brew install lolcat
-
Clone the repository:
git clone https://github.com/m3au/purr.git ~/.zsh/purr -
Source the script in your ZSH configuration (
~/.zshrc):source ~/.zsh/purr/purr.zsh
-
Reload your shell:
source ~/.zshrc
Add to your .zplugins.txt:
m3au/purr
Then run antidote bundle or restart your shell.
-
Clone into custom plugins directory:
git clone https://github.com/m3au/purr.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/purr -
Add to your
.zshrcplugins array:plugins=(... purr)
Before using purr, you need to set up your 1Password vault with the required items:
Create a vault (default name: purr) with the following items:
-
GPG Item (default name:
gpg)- Required fields:
key_id: Your GPG key ID (e.g.,ABC123DEF456)password: Your GPG key passphrasepublic_key: Your public GPG key (paste full key)private_key: Your private GPG key (paste full key)
- Required fields:
-
GitHub Item (default name:
GitHub)- Required fields (one of the following field names):
- Username:
username,user, orlogin - Email:
email,mail, oremail address - Personal Access Token:
pat,token,access token,personal access token, orpassword
- Username:
- Required fields (one of the following field names):
You can customize the vault and item names via environment variables:
# In your ~/.zshrc or ~/.purrrc
export PURR_VAULT_NAME="my-vault-name"
export PURR_GPG_ITEM="my-gpg-item"
export PURR_GITHUB_ITEM="my-github-item"Alternatively, create a ~/.purrrc file:
# purr configuration
export PURR_VAULT_NAME="purr"
export PURR_GPG_ITEM="gpg"
export PURR_GITHUB_ITEM="GitHub"Then source it in your .zshrc before sourcing purr:
[ -f ~/.purrrc ] && source ~/.purrrc
source ~/.zsh/purr/purr.zshGet from zero to productive in under 2 minutes:
git clone https://github.com/m3au/purr.git ~/.zsh/purr
echo "source ~/.zsh/purr/purr.zsh" >> ~/.zshrc
source ~/.zshrcCreate a vault (default: purr) with GPG and GitHub items. See the detailed setup guide for step-by-step instructions.
purr # Load all keys and configure Git signing
purr check # Verify everything is working
purr lock # Securely unload keys when doneThat's it! Your SSH keys, GPG keys, Git signing, and GitHub credentials are all configured and ready to go. 🎉
purr- Loads keys and configures Git signingpurr lock- Unloads keys and locks 1Passwordpurr check- Checks key statuspurr -v- Verbose mode for any commandpurr -h- Shows help message
# Morning: Load all keys
purr
# Verify everything is working
purr check
# Make commits (automatically signed)
git commit -m "Your commit message"
# End of day: Lock everything
purr lock# Install purr
git clone https://github.com/m3au/purr.git ~/.zsh/purr
echo "source ~/.zsh/purr/purr.zsh" >> ~/.zshrc
# Configure 1Password vault with GPG and GitHub items
# (see docs/setup.md for details)
# Load keys
purr
# Verify setup
purr check# Check status with verbose output
purr check -v
# Try loading keys with verbose output
purr -v# Load all keys and configure Git signing
$ purr
ᓚᘏᗢ purr initializing...
✅ 1Password is running and authenticated
Connected to 1Password SSH agent.
GPG key loaded successfully and Git configured for signing.
Credentials loaded:
GitHub: your-username
GitHub Token: ghp_****...****7890
Git signing: Enabled
GPG: ABC1****...****2345
SSH: Connected
ᓚᘏᗢ purr$ purr check
Checking for SSH keys:
SSH keys found:
~/.ssh/id_rsa
~/.ssh/id_ed25519
Checking SSH agent connection:
Connected to SSH agent at ~/Library/Group Containers/.../agent.sock
Loaded keys: 3
Checking for GPG keys:
GPG keys found:
Key ID: ABC123DEF456
Name: Your Name <your@email.com>
Checking Git GPG signing status:
Git GPG signing is enabled.
Signing key: ABC123DEF456
Checking GitHub token status:
GITHUB_TOKEN environment variable: Set (ghp_****...****7890)$ purr lock
System locked
ᓚᘏᗢ hiss
# Verify keys are unloaded
$ purr check
Checking SSH agent connection:
Not connected to any SSH agent.
Checking for GPG keys:
No GPG keys found on this system.When running purr, the GitHub Personal Access Token is:
- Exported as
GITHUB_TOKENenvironment variable - Unset when running
purr lock - Shown in obfuscated format (first 4 and last 4 chars visible)
The default purr command already handles:
- ✅ 1Password integration (authentication and credential retrieval)
- ✅ SSH key management (loads from 1Password SSH agent)
- ✅ GPG key management (imports and configures Git signing)
- ✅ GitHub credentials (configures Git user, email, and stores token in keychain)
- ✅ Git signing (enables GPG commit signing)
Additional commands available:
purr check- Check status of all keyspurr lock- Unload all keys and lock 1Password
purr github- Standalone GitHub credential managementpurr ssh- Standalone SSH key operationspurr gpg- Standalone GPG key operationspurr op- 1Password CLI shortcutspurr key- Key obfuscation utilities
- Bitwarden support
- KeePassXC support
- LastPass support
- Dashlane support
- YubiKey integration
- Multiple key profile support
- Key rotation automation
- Backup and recovery workflows
- Terminal UI with charm.sh
- Cloud key provider integration
- Team key management
- Audit logging
purr includes a comprehensive test suite using bats. Run tests quickly:
brew install bats-core # One-time setup
bun test # Run all tests (~7 seconds)
bun run test:unit # Run unit tests only (~2 seconds)Tests are written using bats. The test structure includes:
tests/test_helper.bats- Common test setup and teardowntests/purr.bats- Main test suite for purr functionstests/unit_obfuscate.bats- Unit tests for obfuscate_key functiontests/mocks/- Mock scripts for external commands (op, gpg, git, ssh)
See CONTRIBUTING.md for guidelines on writing tests.
This project is licensed under the MIT License. See the LICENSE file for details.
For security-related issues, please see SECURITY.md.
Important Security Notes:
- Never share your 1Password vault items or GPG keys
- Always run
purr lockwhen finished to unload keys - Review the script before sourcing it in your shell
- The script automatically obfuscates sensitive data in output
If you see authentication errors:
- Ensure 1Password desktop app is running and you're signed in
- Run
op signinto authenticate with the CLI - Check that 1Password CLI integration is enabled in preferences
If GPG keys aren't loading:
- Verify the GPG key ID matches your actual key
- Check that the passphrase is correct
- Ensure the public and private keys are properly formatted in 1Password
- Try running with
-vflag for verbose output
If SSH keys aren't available:
- Ensure 1Password is running and SSH agent is enabled
- Check that SSH keys are added to 1Password
- Verify the SSH agent socket path (default:
~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock)
If GitHub credentials aren't being set:
- Verify the GitHub item exists in your 1Password vault
- Check that the required fields (username, email, token) are present
- GitHub setup is optional and won't fail if the item is missing
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
This project is licensed under the MIT License. See the LICENSE file for details.