I use gpg in Docker Debian:latest automatic build and the gpg in the terminal it works, but when I use in a script, no matter I do, it asks for the passphrase, I do like this:

passphrase=$(cat /build/secure/passphrase.txt)
echo $passphrase | gpg --passphrase-fd 0 --import /build/secure/gpg/secret-signing-key.pgp

but if I do in the terminal, it works!

Why? How come?

  • What's the output of gpg --version in both the container and on your host? – Jens Erat Sep 17 '17 at 9:28
  • You can also directly use --passphrase-file, without setting the environment variable by reading from a file. Anyway, newer echo passphrases on multi-user machines: all other users will be able to read arguments for all other running applications, even if they're executed by another users. – Jens Erat Sep 17 '17 at 9:41

GnuPG 2, gpg-agent and Loopback Pinentry

GnuPG 2.0 and newer only consider --passphrase-...-options when --batch is also applied. From man gpg:

Note that this passphrase is only used if the option --batch has also been given. This is different from GnuPG version 1.x.

So a working command for GnuPG 2.0 would be:

gpg --batch --passphrase-fd 0 --import <path>

Furthermore, since GnuPG 2.1, gpg-agent handles all secret key operations and also asks for the passphrase. The idea behind this is to have a small core application handling the most critical bits of cryptography, and having the (comparably) large GnuPG with potentially more bugs and security issues application doing all the other stuff. By default, gpg-agent will not query gpg for the passphrase, but try to ask the user directly (which will obviously fail in an unattended build). There is a last escape, though: you can use --pinentry-mode loopback to make gpg-agent query gpg for the passphrase, but as this impacts security as discussed before, you must also configure gpg-agent to allow loopback pinentry.

Add following line to ~/.gnupg/gpg-agent.conf:


Now, you should be able to use following command in GnuPG 2.1 and newer:

gpg --batch --pinentry-mode loopback --passphrase-fd 0 --import <path>

Passing in the gpg-agent Socket

A better option than importing private keys to Docker containers is usually to store (and unlock) the private key on the host, and then passing a gpg-agent socket into the Docker container. This way, the critical secrets never will enter the Docker container, and you can be very sure it will not be stored in the image layers and published by accident.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.