零弐壱蜂

[Git] GPG署名エラー(pinentry)の解決方法

背景

git commit時のGPG署名に失敗した。

以前からGPG署名のパスフレーズを毎回入力していたが、ある時点からpinentry-cursesによる入力ができなくなり、署名が失敗するようになった。

環境

  • macOS(Darwin 24.6.0, arm64)
  • Ghostty 1.3.1
  • GnuPG 2.4.7
  • GPG鍵: ed25519
  • commit.gpgsign = true

状況

git commitを実行すると、以下のエラーが発生しコミットできない。

gpg: signing failed: No such file or directory
fatal: failed to write commit object

このとき、パスフレーズ入力ダイアログは表示されなかった。

原因

GPG署名の流れは以下の通りである。

  1. git commitがGPGに署名を要求する
  2. GPGがgpg-agentを呼び出す
  3. gpg-agentがパスフレーズ入力のためにpinentryを起動する
  4. pinentryが入力ダイアログを表示できないと署名に失敗する

今回の原因は2つある。

  1. GPGがデフォルトのpinentry-cursesを使用していたが、ターミナル環境によってはパスフレーズ入力ダイアログを正しく表示できない場合がある
  2. ~/.gnupg/gpg-agent.confが存在せず、使用するpinentry-programを明示していなかったため、macOS向けのGUI pinentryに切り替わっていなかった

対処法

1. pinentry-mac のインストール

# macOS向けのpinentryをインストール
brew install pinentry-mac

macOSネイティブのGUIダイアログでパスフレーズを入力でき、Keychainへの保存にも対応する。

2. gpg-agent.conf の作成

~/.gnupg/gpg-agent.conf を以下の内容で作成した。

pinentry-program /opt/homebrew/bin/pinentry-mac
default-cache-ttl 34560000
max-cache-ttl 34560000
  • pinentry-program: pinentry-macを使用することで、GUIダイアログとKeychain連携を利用できる
  • default-cache-ttl: パスフレーズのキャッシュ保持時間である
  • max-cache-ttl: キャッシュの最大保持時間である

gpg-agent.confgpg-agentの標準設定ファイルであり、利用するpinentryプログラムをここで指定できる。

3. gpg-agent の再起動

# gpg-agentを停止
gpgconf --kill gpg-agent

# gpg-agentを再起動
gpgconf --launch gpg-agent

設定反映後、初回のgit commit時にGUIダイアログが表示される。「Save in Keychain」にチェックを入れて保存すれば、以降はパスフレーズの入力が不要になる。

4. 動作確認

# 署名のテスト
echo "test" | gpg --clearsign

上記コマンドで署名済みテキストが出力されれば、GPG署名は正常に動作している。

再発防止

gpg-agent.confを変更した場合は、毎回gpg-agentを再起動して設定を反映した方がよい。

また、pinentry-cursesのようなTTY依存のpinentryを使う場合は、シェルの設定ファイルに以下を追加しておくとTTYの不整合を避けやすい。

# ~/.zshrc または ~/.bashrc に追加
export GPG_TTY=$(tty)

今回のようにmacOSでGUIダイアログを使う場合でも、ターミナル切り替え時のトラブルシューティングとして覚えておくと役立つ。

参考