piv-agent is currently going through a heavy refactor: I am removing GnuPG support.
This is for several reasons, including:
- It is terribly complex, and its agent protocol moreso. The agent protocol is also poorly documented.
- Supporting it requires maintenance and several additional dependencies, including one that I had to fork.
- It has well-documented technical problems.
- I don't use it anymore.
To that end, I am planning the following release schedule for piv-agent:
- ✅
v1.xwill be released. It will supportagevia a plugin, in addition to SSH and GPG. - ⏳
v1.xwill be maintained for a short period (6 months). This is so that anyone else usingpiv-agenthas a chance to migrate away from GPG, or find another solution. - ⏳
v2.xwill be released shortly afterv1.x, with GPG support totally removed. Active development will only occur onv2.x.
Please test if you can, but be aware there may be breakage. In particular, the age plugin support is experimental: until this warning is removed, the identity format is unstable.
Discussion of this plan and updates happens here.
piv-agentis an SSH and age plugin agent providing simple integration of PIV hardware (e.g. a Yubikey) withssh, andageworkflows such asgitsigning andpassagepassword storage.piv-agentoriginated as a reimplementation of yubikey-agent because I needed some extra features, and also to gain a better understanding of the PIV applet on security key hardware.piv-agentmakes heavy use of the Go standard library and supplementarycryptopackages, as well aspiv-goandpcsclite. Thanks for the great software!
DISCLAIMER
I make no assertion about the security or otherwise of this software and I am not a cryptographer. If you are, please take a look at the code and send PRs or issues. 💚
piv-agent has a hard dependency on Linux and systemd.
At this time no other OS stack is supported.
- implements (a subset of) both
ssh-agentandgpg-agentfunctionality - implements an age plugin: age-plugin-piv-agent
- support for multiple hardware security keys
- support for multiple slots in those keys
- support for multiple touch policies
- all cryptographic keys are generated on the hardware security key, rather than on your laptop
- secret keys never touch your hard drive
- uses systemd socket activation
- as a result, automatically drop the transaction on the security key and cached passphrases after some period of disuse
- provides "fall-back" to traditional SSH and OpenPGP keyfiles
This agent should require no interaction and in general do the right thing when security keys are plugged/unplugged, laptop is power cycled, etc.
It is highly opinionated:
- Only supports 256-bit ECC keys (P-256) on hardware tokens
- Only supports ed25519 SSH keys on disk (
~/.ssh/id_ed25519) - Only supports the mlkem768p256tag identity/recipient type
- Requires socket activation
It makes some concession to practicality with OpenPGP:
- Supports RSA signing and decryption for OpenPGP keyfiles. RSA OpenPGP keys are widespread and Debian in particular only documents RSA keys.
It tries to strike a balance between security and usability:
- Takes a persistent transaction on the hardware token, effectively caching the PIN.
- Caches passphrases for on-disk keys (i.e.
~/.ssh/id_ed25519) in memory, so these only need to be provided once after the agent starts. - After a period of inactivity it exits, dropping both the transaction and the passphrase. Socket activation restarts it automatically as required.
Tested with:
- YubiKey 5C, firmware versions 5.2.4, 5.7.1.
If you have tested another device or firmware version with piv-agent successfully, please send a PR adding it to this list.
| Supported | Not Supported | Support Blocked (Curve25519) |
|---|---|---|
| ✅ | ❌ | ⏳ |
| Security Key | Keyfile | |
|---|---|---|
| ecdsa-sha2-nistp256 | ✅ | ❌ |
| ssh-ed25519 | ❌ | ✅ |
| Security Key | Keyfile | |
|---|---|---|
| ECDSA Sign (NIST Curve P-256) | ✅ | ✅ |
| ECDH Decrypt | ✅ | ✅ |
| RSA Sign | ❌ | ✅ |
| RSA Decrypt | ❌ | ✅ |
piv-agent, and its age plugin age-plugin-piv-agent only support the mlkem768p256tag identity/recipient type.
Please see the documentation.
Install build dependencies:
# debian/ubuntu
sudo apt install libpcsclite-dev
make
This D-Bus variable is required for pinentry to use a graphical prompt:
go build ./cmd/piv-agent && systemd-socket-activate -l /tmp/piv-agent.sock -E DBUS_SESSION_BUS_ADDRESS ./piv-agent serve --debug
Then in another terminal:
export SSH_AUTH_SOCK=/tmp/piv-agent.sock
ssh ...
cd docs && make serve