Pony: A GPG-Backed Secret Store That Fits in a Single File
Hook
Most password managers are databases pretending to be vaults. Pony is a 600-line Go program that turns your GPG key into the only credential manager you need—and stores everything in one encrypted file you can version control.
Context
The secret management landscape has become absurdly complex. Enterprise solutions like HashiCorp Vault require infrastructure teams to manage. Cloud password managers like 1Password and Bitwarden ask you to trust a third party with your master keys. Browser-based solutions create lock-in and don't handle API tokens or recovery codes well.
For developers who already manage GPG keys for signing commits and encrypting sensitive data, this proliferation of tools feels redundant. Why maintain a separate master password when you already have a well-protected GPG key, possibly backed by a hardware token like a YubiKey? Jessie Frazelle built Pony to answer this question: a local, file-based secret store that delegates all cryptographic heavy lifting to GPG. No new encryption schemes, no cloud sync to trust, no database to corrupt. Just your secrets, encrypted with tools you already use, stored in a single file you control completely.
Technical Insight
Pony's architecture is deceptively simple, which is its greatest strength. The entire secret store lives in ~/.pony (configurable), a GPG-encrypted file containing JSON key-value pairs. Every operation—create, read, list, delete—follows the same pattern: decrypt the file into memory, manipulate a Go map, re-encrypt everything, and write it back.
Here's how you interact with it:
# Store a GitHub token (notice the namespaced convention)
$ pony add com.github.username.token
Enter the secret: ****
# Retrieve it (output goes to stdout)
$ pony get com.github.username.token
ghp_xxxxxxxxxxxxxxxxxxxx
# Use it in scripts without exposing in history
$ export HISTIGNORE="pony*"
$ curl -H "Authorization: token $(pony get com.github.username.token)" https://api.github.com/user
# Store recovery codes with special syntax
$ pony add com.google.recovery
Enter the secret: code1,code2,code3
$ pony get com.google.recovery
code1
code2
code3
The encryption happens through Go's golang.org/x/crypto/openpgp package. When you add a secret, Pony reads your GPG keyring, encrypts the updated JSON payload using your public key, and writes it atomically. Retrieval reverses this: it decrypts using your private key (prompting for your GPG passphrase if needed) and extracts the requested value.
What makes this elegant is the leverage of existing infrastructure. If your GPG key is on a YubiKey, Pony automatically benefits from hardware-backed security. If you use gpg-agent with caching, you won't be prompted for your passphrase on every operation. The tool doesn't reinvent key management—it inherits 30 years of GPG ecosystem maturity.
The recovery code feature demonstrates thoughtful design. Keys ending in .recovery get special treatment: the value is split on commas and displayed one per line. This matches the real-world pattern of backup codes provided by 2FA systems, making them easy to consume programmatically:
# Use the first unused recovery code
$ pony get com.google.recovery | head -n 1
The namespacing convention (com.github.username.token) isn't enforced by the tool but recommended in the README. It's reverse-DNS notation borrowed from Java package naming, preventing collisions and making pony list output scannable. This Unix philosophy approach—provide mechanism, suggest policy—keeps the codebase minimal while encouraging good practices.
One architectural choice worth examining: the single-file, encrypt-everything model. This means adding one secret requires decrypting all secrets. For a personal store with 50-100 entries, this is imperceptible. For thousands, it would lag. But Frazelle made a deliberate tradeoff: simplicity and transparency over performance at scale. The entire storage format is understandable in minutes, backups are cp ~/.pony ~/.pony.backup, and syncing across machines is scp. Compare this to password managers with proprietary binary formats or SQLite databases, where you need specialized export tools and can't easily inspect what's stored.
Gotcha
Pony's simplicity comes with constraints that matter in practice. The single-file architecture has no concurrency control. If you run pony add in two terminals simultaneously, one write will silently clobber the other. There's no file locking, no conflict resolution, no journaling. For personal use on one machine, this rarely surfaces. But if you're syncing via Dropbox or editing from multiple SSH sessions, you'll eventually lose data.
The lack of built-in synchronization means you're responsible for distribution. Some users put ~/.pony in their dotfiles repo, but this requires careful .gitattributes configuration to prevent accidental decryption in CI. Others rsync it across machines. Neither approach handles conflicts gracefully—if you add different secrets on two laptops and sync, manual merge becomes your problem.
GPG dependency is both a feature and a barrier. If your key is passphrase-protected (as it should be) and you haven't configured gpg-agent caching, you'll type your passphrase constantly. If you're on a fresh system without your GPG key, you can't access any secrets until you restore it. The tool provides no degraded access mode, no "view-only" capability. This is philosophically consistent but practically painful during key rotation or system migrations.
Verdict
Use if: You already manage a GPG key for code signing or email encryption, you're comfortable with command-line tools, and you want a transparent secret store you can version control or sync manually. Pony excels for personal API token management, storing recovery codes, and situations where you need programmatic access to secrets in shell scripts without reaching for a password manager's clunky CLI. It's ideal if you value auditability and full control over your data, or if you're running headless Linux systems where GUI password managers are awkward.
Skip if: You need to share secrets with a team (no multi-user support), you want mobile access (no apps exist), or you're managing hundreds of secrets (performance degrades). Also skip if you haven't set up GPG yet—don't learn GPG just for this tool; use a dedicated password manager instead. If you need browser integration, automatic sync across devices, or audit logs for compliance, mature solutions like 1Password or Bitwarden are better fits despite their complexity.