Keep GnuPG credentials cached for entire user session

Solution 1:

Up to GnuPG 2

The user configuration (in ~/.gnupg/gpg-agent.conf) can only define the default and maximum caching duration; it can't be disabled.

The default-cache-ttl option sets the timeout (in seconds) after the last GnuPG activity (so it resets if you use it), the maximum-cache-ttl option set the timespan (in seconds) it caches after entering your password. The default value is 600 seconds (10 minutes) for default-cache-ttl and 7200 seconds (2 hours) for maximum-cache-ttl.

Set it to a year or so – say, 34560000 seconds (400 days) – and you should be fine:

default-cache-ttl 34560000
maximum-cache-ttl 34560000

But for this change to take effect, you need to end the session by restarting gpg-agent.

If you want to limit to your session length, you'd need to kill the daemon at logout. This is very different between operating systems, so I'm referring to another question/answer containing hints for different systems.

You could also restart the gpg-agent during login, but this does not limit caching time to the session length, but logins of a user. Decide yourself if this is a problem in your case.

GnuPG 2.1 and above

In GnuPG 2.1 and above, the maximum-cache-ttl option was renamed to max-cache-ttl without further changes.

Solution 2:

For Windows

The file you need to edit should be placed at: ~\.gnupg\

If you run that in a PowerShell window it will open: C:\Users\<UserName>\.gnupg

Just put the gpg-agent.conf file there with whatever values you like.

You can verify it took by running:

  1. gpgconf.exe --reload gpg-agent
  2. gpgconf.exe --list-options gpg-agent

You can also use this one liner: Set-Content -Path ~\.gnupg\gpg-agent.conf -Value "default-cache-ttl 86400$([System.Environment]::NewLine)max-cache-ttl 86400"

Older Versions Of GPG

In older versions, the file was at: $env:AppData\gnupg (C:\Users\<UserName>\AppData\Roaming\gnupg)

So if you can't find it at ~\.gnupg\gpg-agent.conf look there.

Solution 3:

Make sure to reload your gpg agent with gpg-connect-agent reloadagent /bye after changing the config.

Solution 4:

Since your problem is you need more or unlimited cache time for passphrase, then you can use gpg-preset-passphrase to cache your gpg password, and you will have unlimited cache time until the agent is restarted / reloaded. Read the documentation here:

gpg-preset-passphrase:

Passphrases set with this utility don’t expire unless the --forget option is used to explicitly clear them from the cache — or gpg-agent is either restarted or reloaded (by sending a SIGHUP to it). Note that the maximum cache time as set with --max-cache-ttl is still honored. It is necessary to allow this passphrase presetting by starting gpg-agent with the --allow-preset-passphrase.

Documentation

Example how to cache password using gpg-preset-passphrase utility in bash:

#!/bin/bash
GPG_PRESET_PASS="/usr/libexec/gpg-preset-passphrase"
KEY_GRIP=$(gpg --with-keygrip --list-secret-keys $KEY_ID | grep -Pom1 '^ *Keygrip += +\K.*')
read -s -p "[$script_name]: Enter passphrase to cache into gpg-agent: " PASSPHRASE; echo
$GPG_PRESET_PASS -c $KEY_GRIP <<< $PASSPHRASE
RETVAL=$?
if [ $RETVAL = 0 ]; then
    echo "OK"
else
    echo "NOT OK"
fi