gpg --encrypt -r: Encrypt Secrets to a Recipient
gpg --encrypt -r encrypts data so only the holders of the named recipient keys can read it.
A common pattern is encrypting a secrets bundle to the CI key in the repo, then decrypting it on the runner. -r selects the recipient by their public key.
What it does
gpg --encrypt encrypts the input to one or more recipient public keys named with --recipient (-r); only the matching secret keys can decrypt it. With --symmetric instead, it encrypts with a passphrase and no key at all.
Common usage
# public-key encryption to a recipient
gpg --encrypt --recipient ci@example.com --armor secrets.env
# multiple recipients
gpg --encrypt -r alice@example.com -r bob@example.com secrets.env
# passphrase-only (symmetric), non-interactive
gpg --batch --symmetric --cipher-algo AES256 \
--passphrase "$KEY" --pinentry-mode loopback secrets.envOptions
| Flag | What it does |
|---|---|
| --encrypt / -e | Encrypt to recipient public keys |
| --recipient <id> / -r | Add a recipient (repeatable) |
| --symmetric / -c | Encrypt with a passphrase instead of a key |
| --armor / -a | ASCII-armor the ciphertext |
| --cipher-algo <name> | Choose the symmetric cipher, e.g. AES256 |
| --trust-model always | Encrypt without prompting about recipient trust |
In CI
When encrypting to an imported recipient key whose owner trust is unset, gpg prompts "use this key anyway?" and hangs. Add --trust-model always (or set owner trust) so the encrypt step never blocks. For passphrase-only secrets, --symmetric with --batch --pinentry-mode loopback keeps it non-interactive.
Common errors in CI
"gpg: <id>: skipped: No public key" means the recipient key is not imported. "gpg: <id>: There is no assurance this key belongs to the named user" followed by a hang is the trust prompt; add --trust-model always. With --symmetric, a no-TTY passphrase prompt raises "Inappropriate ioctl for device"; use loopback.