Skip to content
Latchkey

gpg --batch and --pinentry-mode loopback

gpg --batch plus --pinentry-mode loopback and --passphrase-fd let GnuPG run with no terminal and no prompts.

This is the flag combination that makes gpg behave in CI. Without it, GnuPG 2.x tries to open pinentry and fails on a runner with no TTY.

What it does

--batch disables interactive prompts and makes gpg fail rather than ask. --yes auto-confirms overwrites. --pinentry-mode loopback tells GnuPG 2.x to take the passphrase from gpg itself instead of launching pinentry. --passphrase-fd reads the passphrase from a file descriptor, and --passphrase passes it directly (less safe).

Common usage

Terminal
# pass the passphrase on fd 0 (stdin) rather than the command line
echo "$GPG_PASSPHRASE" | gpg --batch --yes \
  --pinentry-mode loopback --passphrase-fd 0 \
  --detach-sign --armor file.tar.gz
# direct passphrase (simpler, but visible in process list)
gpg --batch --pinentry-mode loopback \
  --passphrase "$GPG_PASSPHRASE" --clearsign notes.txt

Options

FlagWhat it does
--batchNon-interactive mode; never prompt
--yesAssume yes to questions like overwrite
--pinentry-mode loopbackTake the passphrase from gpg, not pinentry
--passphrase-fd <n>Read the passphrase from a file descriptor
--passphrase <x>Pass the passphrase inline (can leak via ps)
--no-ttyNever write to or read from the terminal

In CI

Non-interactive batch mode is essential in CI; a runner has no terminal for pinentry to attach to. Prefer --passphrase-fd over --passphrase so the secret does not appear in the process list. Loopback mode also requires that gpg-agent allows it: with older agents add allow-loopback-pinentry to gpg-agent.conf.

Common errors in CI

"gpg: signing failed: Inappropriate ioctl for device" means loopback mode is not set and gpg tried to prompt. "gpg: setting pinentry mode 'loopback' failed: Not supported" means the agent forbids loopback; add allow-loopback-pinentry to gpg-agent.conf and reload the agent. "gpg: Sorry, no terminal at all requested" appears when --batch is set but a prompt was still reached.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →