Read-only device inventory
Inspect USB/NFC, firmware and FIDO2, OTP, PIV and OpenPGP capabilities on both devices without changing slots.
Hardware authentication and continuity
A primary key for daily use and a separate backup key for recovery. This page describes the intended architecture and read-only verification, not a live device inventory.
Public conceptual diagram. No serial numbers, PINs/PUKs, OTP seeds, private keys, personal certificates, escrow paths or account identifiers are published. 'Documented' reflects a past observation, not a check performed today.
Select a node to explore its role. Links describe intended dependencies, not automatic synchronization of private keys between devices.
The backup YubiKey must be enrolled separately with each service; its private keys are not cloned automatically.
Inspect USB/NFC, firmware and FIDO2, OTP, PIV and OpenPGP capabilities on both devices without changing slots.
Enroll both keys separately on each critical account, retain an independent recovery method, and test sign-in with each.
Keep a dedicated backup hardware SSH key (ed25519-sk), verify touch and PIN requirements, and test access non-destructively.
Inspect slots (including 9A and 82), expiration and trust chain; renew expired certificates only after backup and explicit authorization.
Document OpenPGP and GPG-agent/pcscd integration; distinguish PIV certificates, OpenPGP subkeys and FIDO-backed SSH.
Keep the legacy challenge-response mechanism separate from FIDO2. Validate the slot and client without revealing or reprogramming the secret.
Create two separate age archives; validate fingerprints and recovery paths without secrets in logs. Stop if both backups refer to the same file.
Verify unlock using the primary key and a backup scenario; document dependencies and rotation after loss.
Simulate losing the primary key: critical accounts, SSH, vault, certificates, archive recovery and redacted evidence.
Illustrative commands for an already configured environment. Variables prefixed with $ and hostnames are examples. This page never provisions a physical YubiKey.
Enroll both YubiKeys separately on GitHub, Cloudflare, or another WebAuthn-compatible identity provider. Test each key independently.
Prerequisites : Compatible account, existing working access, and independent recovery method.
Caution : Use the service security settings: register the primary and backup keys separately. Do not depend on one authenticator.
Reference : FIDO Alliance
Use an already-enrolled ed25519-sk hardware identity. Authentication normally requires touch and optionally PIN.
Prerequisites : FIDO-enabled OpenSSH, public key registered in authorized_keys, and independent SSH recovery access.
Caution : Do not replace the only working SSH access. The local key file is a handle, not the hardware private key.
ssh -V
ssh -i ~/.ssh/id_ed25519_sk user@host.exampleReference : Yubico SSH FIDO2
Sign commits with a dedicated FIDO-backed SSH identity, preferably separate from the SSH login key.
Prerequisites : Existing ed25519-sk signing identity; public key registered for signing on GitHub; compatible Git.
Caution : These commands change repository-local Git settings. A GitHub Verified badge still requires server-side verification.
git config --local gpg.format ssh
git config --local user.signingkey "$HOME/.ssh/id_ed25519_sk_git_signing.pub"
git config --local commit.gpgsign trueReference : Yubico Git FIDO2
Use an OpenPGP signing subkey stored on the YubiKey. Git invokes gpg-agent and may require touch/PIN.
Prerequisites : Working OpenPGP signing subkey and gpg-agent; verified public fingerprint.
Caution : Do not confuse PIV, OpenPGP, and FIDO-backed SSH keys. Do not automate PIN or key changes.
gpg --card-status
git config --local gpg.format openpgp
git config --local user.signingkey "$GPG_SIGNING_FINGERPRINT"
git config --local commit.gpgsign trueReference : GitHub signing commits
Keep sensitive configuration encrypted in Git and inject it only when needed. SOPS uses an age recipient, either software-based or via a YubiKey plugin.
Prerequisites : Already encrypted file, recipient configured in .sops.yaml, accessible age identity, approved local dev command.
Caution : Never commit plaintext .env files or print environment secrets. Software age identities are not automatically YubiKey-backed.
sops edit config/dev.enc.yaml
sops exec-env config/dev.enc.yaml 'just dev-up'Reference : SOPS
Decrypt workstation development secrets using an already-provisioned YubiKey age identity, without persisting plaintext. Access follows the configured device PIN/touch policy.
Prerequisites : Existing age-plugin-yubikey identity, readable identity descriptor, compatible plugin installed, YubiKey recipient already present in the SOPS policy, and a separate recovery recipient.
Caution : This is a read/decrypt workflow, not PIV provisioning. exec-env requires flat top-level scalar secrets; do not print the environment or commit decrypted credentials.
age-plugin-yubikey --list
SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/yubikey-identity.txt" \
sops exec-env config/dev.enc.yaml 'just dev-up'Reference : age-plugin-yubikey
After explicitly approved age-plugin-yubikey provisioning, encrypt for the hardware recipient and decrypt with the plugin identity file.
Prerequisites : Installed plugin, approved PIV slot, backed-up plugin identity file, verified recipient, independent recovery plan.
Caution : Initial plugin setup can mutate a PIV slot: never run it without approval. An identity stored on a USB drive is not automatically hardware-resident.
age-plugin-yubikey --list
age -r "$AGE_YUBIKEY_RECIPIENT" -o artifact.age artifact.txt
age -d -i "$AGE_YUBIKEY_IDENTITY_FILE" artifact.age | sha256sumReference : age-plugin-yubikey
Encrypt a pg_dump stream directly without creating an intermediate plaintext dump. Use multiple independent recovery recipients.
Prerequisites : Restricted pg_dump permissions, verified age recipients in recipients.txt, secured backup storage, planned recovery drill.
Caution : Listing an archive is not a full restore test. Use independent recovery recipients and verify pipeline exit status.
set -o pipefail
pg_dump -Fc --no-owner "$PGDATABASE" | age -R recipients.txt -o postgres.dump.age
age -d -i "$AGE_IDENTITY_FILE" postgres.dump.age | pg_restore --listReference : PostgreSQL pg_dump
Add a detached signature to an already encrypted archive to verify origin and integrity before a restore.
Prerequisites : YubiKey-accessible GPG signing subkey, existing postgres.dump.age file, trusted signer public key.
Caution : A signature does not encrypt a backup. Check the signer fingerprint and verify before restoring.
gpg --local-user "$GPG_SIGNING_FINGERPRINT" --detach-sign --armor --output postgres.dump.age.asc postgres.dump.age
gpg --verify postgres.dump.age.asc postgres.dump.ageReference : GnuPG
Inspect the slot 9a authentication certificate, its issuer and expiration. For TLS client authentication, configure PKCS#11 middleware.
Prerequisites : Connected YubiKey, ykman installed, existing certificate, approved trust chain.
Caution : Export is public certificate only, but may expose personal identity information. Do not publish; never regenerate keys during diagnostics.
ykman piv info
ykman piv certificates export 9a auth-public.pem
openssl x509 -in auth-public.pem -noout -subject -issuer -datesReference : Yubico PIV
Use WebAuthn/FIDO2 for vault login, enroll a second key independently and verify offline recovery codes.
Prerequisites : Compatible server/client, recovery session, securely stored recovery code.
Caution : In account settings, turn on WebAuthn two-step login and independently enroll and test both keys.
Reference : Bitwarden two-step login
Protect human HashiCorp Vault login with an OIDC identity provider enforcing FIDO2/WebAuthn; Vault can also apply supported native MFA methods.
Prerequisites : Configured OIDC method in Vault and upstream identity provider enforcing FIDO2.
Caution : Vault does not automatically offer native WebAuthn MFA. Distinguish IdP MFA from Vault's built-in login MFA.
vault login -method=oidcReference : HashiCorp Vault MFA
Bind a KeePassXC database to the YubiKey HMAC-SHA1 OTP challenge-response slot. Plan independent recovery.
Prerequisites : Existing challenge-response slot, compatible KeePassXC, test copy of the database and validated recovery plan.
Caution : Never reprogram an OTP slot without secure secret backup. Separate keys cannot automatically unlock the same database.
Reference : KeePassXC
Keep OATH-TOTP credentials on the YubiKey and obtain codes through Yubico Authenticator when WebAuthn is unavailable.
Prerequisites : Provisioned OATH app, TOTP-enabled service and recovery method.
Caution : TOTP is less phishing-resistant than WebAuthn. OATH-TOTP and the HMAC-SHA1 OTP challenge-response slot are separate applications.
Reference : Yubico Authenticator
Terms used throughout the diagram and plan.
Fast IDentity Online 2
Strong authentication standard with hardware keys, including passwordless sign-in.
Web Authentication
Browser API to register and authenticate a security key.
Client to Authenticator Protocol
Protocol between the client system and a hardware authenticator.
Secure Shell
Remote access protocol; the -sk key type uses a FIDO authenticator.
Personal Identity Verification
Smartcard application for certificate-based authentication and cryptographic operations.
Public-Key Cryptography Standards #11
Standard interface to cryptographic modules and smartcard objects.
GNU Privacy Guard
Software to manage OpenPGP keys and signatures.
Open Pretty Good Privacy
Open standard for signing and encrypting data.
One-Time Password
Single-use password; not the same as WebAuthn.
Hash-based Message Authentication Code
Authentication code derived from a secret key and hash function.
Secure Hash Algorithm 1
Legacy hash function used by some challenge-response modes; not a recommendation for new digital signatures.
Near Field Communication
Short-range radio communication with phones and readers.
Personal Identification Number
Personal code protecting key access.
PIN Unblocking Key
Unlock code for the PIV application, kept offline.
Certificate Authority
Authority issuing or signing certificates.
age encryption tool
File encryption tool used for encrypted recovery archives.
Multi-Factor Authentication
Authentication with multiple independent factors, for example a password and hardware key.
Secrets OPerationS
Editor and encryption tool for structured secrets, including age recipients.
OpenID Connect
Identity protocol built on OAuth 2.0, used for federated Vault login.
Identity Provider
Provider authenticating users and optionally enforcing WebAuthn.
Initiative for Open Authentication
Standards for authentication passcodes, distinct from the OTP challenge-response application.
Time-based One-Time Password
Short-lived time-based code, often six digits.
Transport Layer Security
Protocol securing network connections, optionally using client certificates.
ITU-T X.509
Standard for public-key certificate format and validation.
Structured Query Language
Database language used by PostgreSQL.
Reference documentation: Yubico · FIDO Alliance · age