A secure pinentry program that retrieves passwords from ProtonPass for GPG and SSH operations, eliminating manual passphrase entry.
# macOS
brew install gnupg protonpass-cli
# Linux (Debian/Ubuntu)
apt install gnupg
# Install pass-cli from https://github.com/protonpass/pass-cli/releasesgit clone https://github.com/damoun/pinentry-proton.git
cd pinentry-proton
make build
sudo make installpass-cli login
pass-cli item create login \
--vault "Personal" \
--title "GPG Key" \
--password "your-key-passphrase"mkdir -p ~/.config/pinentry-proton
cat > ~/.config/pinentry-proton/config.yaml << 'EOF'
default_item: "pass://Personal/GPG Key/password"
EOFmkdir -p ~/.gnupg
echo "pinentry-program /usr/local/bin/pinentry-proton" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agentThat's it. GPG and SSH operations will now retrieve passphrases from ProtonPass automatically.
- GPG/SSH agent requests a PIN via the pinentry protocol
- Pinentry-Proton matches the request to a configured ProtonPass item
- Retrieves the password using
pass-cli item view pass://VAULT/ITEM/FIELD - Returns the password to the agent and zeros it from memory
Workflow: Unlock ProtonPass once at the start of your session, then sign commits, encrypt files, and SSH without re-entering PINs.
- Go 1.21+ (for building)
- ProtonPass CLI (pass-cli) installed and configured
- Active ProtonPass session (
pass-cli login)
Create ~/.config/pinentry-proton/config.yaml:
# Default item if no mapping matches
default_item: "pass://Personal/Default Key/password"
# Timeout in seconds (default: 60)
timeout: 60
# Map pinentry contexts to ProtonPass items
mappings:
- name: "GitHub SSH Key"
item: "pass://Work/GitHub SSH Key/password"
match:
description: "github"
- name: "Personal GPG Key"
item: "pass://Personal/GPG Key/passphrase"
match:
keyinfo: "ABCD1234"See config.example.yaml for more examples.
Config file locations (checked in order):
$PINENTRY_PROTON_CONFIG$XDG_CONFIG_HOME/pinentry-proton/config.yaml$HOME/.config/pinentry-proton/config.yaml$HOME/.pinentry-proton.yaml
- Case-insensitive substring matching
- All specified criteria must match (AND logic)
- First matching mapping wins
- Falls back to
default_itemif no match
Use PINENTRY_PROTON_DEBUG=1 to see what context values GPG/SSH sends, then configure your mappings accordingly.
pass://VAULT_NAME/ITEM_TITLE/FIELD
pass://SHARE_ID/ITEM_ID/FIELD
Field defaults to password if omitted. Verify your URI works with:
pass-cli item view 'pass://Personal/GPG Key/password'YubiKey GPG cards prompt for a PIN when signing. To automate this:
- Find your card's keygrip:
gpg --card-statusthengpg --with-keygrip -K YOUR_FINGERPRINT - Store your card PIN in ProtonPass
- Map the keygrip in your config:
mappings:
- name: "YubiKey PIN"
item: "pass://Personal/YubiKey PIN/password"
match:
keyinfo: "YOUR_KEYGRIP_HERE"Configure GPG agent to handle SSH by adding to ~/.gnupg/gpg-agent.conf:
enable-ssh-support
pinentry-program /usr/local/bin/pinentry-proton
Then add to your shell profile:
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
gpgconf --launch gpg-agentOn macOS, also add UseKeychain no to ~/.ssh/config.
"No ProtonPass item configured for this context" — Add a mapping or default_item to your config.
"Failed to retrieve password" — Check: pass-cli login, correct item URI, network connectivity. Debug with:
pass-cli item view 'pass://YOUR_VAULT/YOUR_ITEM/password'"pass-cli: command not found" — Install ProtonPass CLI from protonpass/pass-cli.
Agent not using pinentry — Verify pinentry-program is set in ~/.gnupg/gpg-agent.conf, then gpgconf --kill gpg-agent.
make build # Build the binary
make check # Run fmt, vet, lint, test
make test-unit # Unit tests
make test-e2e # E2E tests (mock pass-cli, no auth needed)
make lint # Run linters
make coverage # Coverage reportSee CONTRIBUTING.md for development guidelines and test/README.md for test details.
pinentry-proton/
├── cmd/pinentry-proton/ # Application entry point
├── internal/
│ ├── config/ # Configuration loading and matching
│ ├── protocol/ # Pinentry Assuan protocol implementation
│ └── protonpass/ # ProtonPass CLI integration
├── test/ # E2E tests, integration tests, fixtures
├── config.example.yaml # Example configuration
└── Makefile # Build automation
- ARCHITECTURE.md — Technical architecture and design
- SECURITY.md — Security policy and threat model
- CONTRIBUTING.md — Contribution guidelines
MIT License — See LICENSE file for details.