gpg --decrypt: Decrypt Secrets in a Pipeline
gpg --decrypt recovers the plaintext of an OpenPGP-encrypted file using your secret key or passphrase.
Decrypting secrets on the runner is the other half of the encrypt pattern. The key is feeding the passphrase non-interactively so the job never stalls on a prompt.
What it does
gpg --decrypt reads an encrypted message and writes the plaintext. For public-key encryption it uses the matching imported secret key; for --symmetric data it uses a passphrase. The decryption also verifies any signature the message carries.
Common usage
# public-key decryption with a passphrase-protected secret key
gpg --batch --pinentry-mode loopback \
--passphrase "$GPG_PASSPHRASE" \
--output secrets.env --decrypt secrets.env.gpg
# symmetric (passphrase-only) decryption
gpg --batch --pinentry-mode loopback \
--passphrase "$KEY" --decrypt secrets.env.gpg > secrets.envOptions
| Flag | What it does |
|---|---|
| --decrypt / -d | Decrypt the input |
| --output <file> / -o | Write plaintext to a file instead of stdout |
| --pinentry-mode loopback | Take the passphrase from the command line / fd |
| --passphrase <x> | Supply the passphrase (use --passphrase-fd in real CI) |
| --batch / --yes | Non-interactive, auto-answer prompts |
In CI
GnuPG 2.x always routes passphrases through the agent and pinentry, so in CI you must add --pinentry-mode loopback and supply the passphrase via --passphrase-fd (safer than --passphrase, which can leak through the process list). Set GNUPGHOME to an ephemeral directory so nothing persists between jobs.
Common errors in CI
"gpg: decryption failed: No secret key" means the secret key for that recipient is not imported, or you imported only the public key. "gpg: public key decryption failed: Inappropriate ioctl for device" is the passphrase prompt with no TTY; add --pinentry-mode loopback. "gpg: decryption failed: Bad session key" with --symmetric means the wrong passphrase.