Keychain

Agent and keyring management for credential caching on Linux.

GNOME Keyring / Secret Service

On Linux desktops, gnome-keyring or kwallet implements the Secret Service D-Bus API. Applications store credentials here automatically.

List stored secrets via secret-tool
secret-tool search --all service login
Store a credential in the keyring
secret-tool store --label="DB Password" service db-prod user admin
Retrieve a stored credential
secret-tool lookup service db-prod user admin
Clear a stored credential
secret-tool clear service db-prod user admin

SSH Agent

Start ssh-agent and add default key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
List loaded identities
ssh-add -l
Add key with time-limited lifetime
ssh-add -t 4h ~/.ssh/id_ed25519
Remove all identities
ssh-add -D
Confirm before each use — prompts via SSH_ASKPASS
ssh-add -c ~/.ssh/id_ed25519

GPG Agent

Check agent status
gpg-connect-agent 'getinfo version' /bye
Restart GPG agent — fixes stale cache, "no secret key" errors
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent
Flush cached passphrases
gpg-connect-agent reloadagent /bye
gpg-agent.conf — cache TTL settings
default-cache-ttl 3600      # Seconds before re-prompting (1 hour)
max-cache-ttl 86400          # Maximum cache lifetime (24 hours)
enable-ssh-support           # GPG agent as SSH agent replacement

systemd Credential Management

On systemd-based systems, systemd-creds provides encrypted-at-rest credentials for services.

Encrypt a credential for a service
echo -n "s3cret" | sudo systemd-creds encrypt --name=db-password - /etc/credstore.encrypted/db-password
Reference in a unit file
[Service]
LoadCredentialEncrypted=db-password:/etc/credstore.encrypted/db-password
Environment=DB_PASS=%d/db-password

Agent Forwarding — Security Considerations

Agent forwarding (ssh -A) exposes your local keys to the remote host’s root user. Prefer ProxyJump instead.

Unsafe — agent forwarding
ssh -A jumphost
ssh internal-host   # Uses forwarded agent — jumphost root can steal keys
Safe — ProxyJump, no agent exposure
ssh -J jumphost internal-host

Or in ~/.ssh/config:

Host internal-host
    ProxyJump jumphost
    IdentityFile ~/.ssh/id_ed25519