Headless and CI GPG¶
status and check do not need a key. seal, unseal, get and
rotate do. This page is how to unlock GPG when there is no pinentry.
The service-vault howto is a different problem: a dedicated empty-passphrase key for one machine. Do not unlock a personal passphrase-protected key in CI if a service vault can hold the secret instead.
Throwaway unprotected key (CI)¶
This is what .github/workflows/ci_test.yml does.
GNUPGHOME=$(mktemp -d)
chmod 700 "$GNUPGHOME"
export GNUPGHOME
cat > "$GNUPGHOME/keygen.txt" <<'EOF'
%no-protection
Key-Type: RSA
Key-Length: 2048
Name-Real: CI Test
Name-Email: ci@nimvault.test
Expire-Date: 0
%commit
EOF
gpg --batch --gen-key "$GNUPGHOME/keygen.txt"
Use that key as recipient. Delete GNUPGHOME at the end of the job.
Loopback pinentry for a real key¶
Only when the job must open an existing key and a service vault is not an option.
gpg-connect-agent /bye
gpg --batch --pinentry-mode loopback --passphrase-file "$PASSPHRASE_FILE" \
--decrypt .vault/manifest.gpg >/dev/null
nimvault unseal
Keep the passphrase in the CI secret store, not in the repository. Prefer
--passphrase-file over putting the passphrase on argv (/proc/<pid>/cmdline
is world-readable).
When not to do this¶
If the machine is unattended and only needs a subset of secrets, make a
service vault with its own empty-passphrase key and wrap rules. See
service vaults.