SSH で Git コミットに署名する

1Passwordマニュアル|Gitバージョン2.34以降でSSHキーを使ったコミット署名方法を解説。GPGキー不要でセキュアな開発環境を実現します。

SSHでGitコミットに署名する

Gitバージョン 2.34 以降では、SSH鍵を使ったコミットとタグの署名がサポートされており、GPGキーは必要ありません。

つまり、1Password SSH統合を使うと、数秒で新しいGit署名鍵をCreateし、秘密鍵を1Passwordから出さずにターミナルアプリやその他のGitクライアントで利用できます。1PasswordアプリでSSHを使ってGitコミット署名を自動的に設定することもできます。

コミットに署名すると、GitHubまたはGitLabアカウントに関連付けられた SSH公開鍵を使って暗号的に検証できるため、他の人は変更が実際にあなたによって行われたことを確認できます。リポジトリーへのプッシュ権限を持つ全ユーザーが任意のCreate者として新しいコミットをプッシュできるので、コミットが署名されていない場合は他のユーザーがなりすますことができるため、コミットに署名をすることが重要です。

1Passwordを使ってGitコミットに署名するのがいかに簡単かを知ってください。

必要条件

始める前に、次のことを行う必要があります。

ステップ1:SSHでGitコミットに署名する

SSHを使ってGitコミット署名をグローバルに自動的に設定するには以下のようにします。

  1. 1Password デスクトップ アプリで使うSSH鍵を開いてください。

  2. ⁝をクリックして[Configure Commit Signing]を選んでください。

  3. 次のウィンドウで、[Edit Automatically]をクリックします。 または、[Copy Snippet]をクリックして、スニペットを~/.gitconfigファイルに手動で貼り付けます。

単一のリポジトリーでSSH署名を設定することもできます。

1PasswordはGitの設定ファイルに次の変更を加えます。

  • gpg.formatをsshに設定します。

  • コミットに署名するためにuser.signingkeyを公開鍵に選択する設定します。

  • commit.gpgsignをtrueに設定すると、各コミットにフラグ-Sを含める必要がなくなります(オプション)

  • gpg.ssh.programを1Passwordが提供するSSH署名バイナリーに設定すると、自分でSSH_AUTH_SOCKを設定する必要がなくなります(オプション)

ヒント

WindowsマシンでWSLを使う場合は、1Password WSL統合を設定してSSH および Gitコマンドを認証し、WSL内でGitコミットに署名する方法を学んでください。

ステップ2:公開鍵を登録する

SSHコミット署名をローカルで設定したので、他のユーザーがコミットの信頼性を検証できるように公開鍵を登録する必要があります。

GitHubの場合

GitHubがコミットを検証できるようにするには、GitHub SSH鍵設定にアクセスして、コミット署名用のSSH鍵を登録します。1Passwordブラウザーエクステンションを使うと、公開鍵と鍵のタイトルを自動的に入力できます。

SSH鍵をコミットの署名に使用できるように、[Key type]を必ず[Signing key]に設定してください。

Gitlabの場合

GitLab がコミットを検証できるようにするには、GitLab SSH鍵設定にアクセスして、コミット署名用のSSH鍵を登録します。1Passwordのブラウザーエクステンションを使うと、公開鍵とキーのタイトルを自動的に入力できます。

SSH鍵をコミットの署名に使用できるようにするには、 [Usage type]を[Authentication & Signing]または[Signing」に設定してください。

ローカルの場合

SSH署名をローカルで検証するには、許可された署名者ファイルをCreateし、それを使うようにGi を設定する必要があります。

これをグローバルに設定することもできます。 例:

$ touch ~/.ssh/allowed_signers $ git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers

または、単一のリポジトリーに結び付けるには、次のようにします。

$ touch .git/allowed_signers $ git config --local gpg.ssh.allowedSignersFile .git/allowed_signers

許可された署名者ファイルに、信頼したい電子メールと公開鍵のペアを追加します。

許可された署名者の例: [email protected] ssh-ed25519 AAAAC3NzaC1IZDI1NTE5AAAAIFIUXAdv5sWOrfZFEPAW8liKjBW3sFxuaNITBWwtFKO

このファイルを他のユーザーと共有したり、CODEOWNERSファイルと同様にGitにチェックインすることも検討できます。

ステップ3:コードをコミット&プッシュする

これで全ての設定が完了したので、コードをコミットできます。

git commit -m "Signing my first commit with SSH"

1Passwordアプリのロックを解除するのと同じ方法(例えばTouch IDまたは Windows Helloを使う方法)で SSH鍵を認証するように求められます。

git commit コマンドが表示されている Mac ターミナルに、Touch ID によるコミット署名キーの使用を承認するように求める 1Password プロンプトが重ねて表示されます。

プッシュとプルに使うのと同じキーを使用して署名することを選択した場合は、追加の認証を必要とせずにプッシュすることもできます。

git push

ステップ4:コミット署名を検証する

GitHubの場合

GitHub でコミット履歴を見ると、SSH署名されたコミットにVerifiedバッジが表示されているのが分かります。それをクリックすると、署名に使われたSSH鍵が表示されます。

GitLabの場合

GitLabでコミット履歴を見ると、SSH署名されたコミットにVerifiedバッジが表示されているのが分かります。それをクリックすると、署名に使われたSSH鍵が表示されます。

ローカルの場合

コミットをローカルで検証するには、次のコマンドを実行します。

git log --show-signature

高度な設定

単一リポジトリーだけにコミット署名を設定する

グローバルではなく、特定のリポジトリーまたはディレクトリーに対してSSHによるGitコミット署名を有効にすることができます。これを行うには、次の手順を実行します。

  1. 1Password デスクトップ アプリで使うSSH鍵を開きます。

  2. ⁝> Configure Commit Signingと移動します。

  3. 次のウィンドウで、[Copy Snippet]をクリックします。

  4. グローバルの~/.gitconfigファイルではなく、リポジトリーの<git-repo>/.git/configファイルにスニペットを貼り付けます。

複数のコミット署名設定を設定する

複数のコミット署名設定を設定する場合は~/.gitconfig内で、includeIfディレクティブを使用できます。

例えばデフォルトとして1PasswordでのSSHコミット署名設定を使用し、/work/acmeサブディレクトリーに1Password以外のGPG設定を使うには、次のようにします。

~/.gitconfigの例

[user] name = Wendy Appleseed email = [email protected] signingkey = ssh-ed25519 AAAAC3NzaC1IZDI1NTE5AAAAIFIUXAdv5sWOrfZFEPAW8liKjBW3sFxuaNITBWwtFKO

[commit] gpgsign = true

[gpg] format = ssh

[gpg "ssh"] program = /Applications/1Password.app/Contents/MacOS/op-ssh-sign

[includeIf "gitdir:~/work/acme/"] path = ~/work/acme/.gitconfig

~/work/acme/.gitconfigの例

[user] email = [email protected] signingkey = 6A40D13BBB936F443084E8C9292E4F983136B860

[gpg] format = openpgp

この例では、~/work/acme下の全リポジトリーはGPG設定を使用し、その他の全ての場所ではSSH設定が使用されます。

ヘルプを受ける

GitがSSHがサポートされていない形式だと言った場合

次のエラーメッセージが表示される場合は、Gitのバージョンが古くなっている可能性があります。

error: unsupported value for gpg.format: ssh

SSHコミット署名のサポートは、Gitバージョン2.34で追加されました。Gitのバージョンを確認するには、次のコマンドを実行します。

git --version

オペレーティングシステムやGit GUIクライアントには、古いバージョンのGitが同梱されていることがよくあります。より最新バージョンをインストールするには、Gitのインストール ドキュメントを参照してください。

Git GUIクライアントの場合は、アプリの設定をチェックして、Gitバイナリーをより最新バージョンに変更できるかどうかを確認します。

Gitの設定を変更した後にコミットが失敗した場合

次のいずれかのエラーメッセージが表示された場合、それはuser.signingkey値に関連している可能性があります。有効なSSH公開鍵に設定されていることを確認してください。

fatal: failed to write commit object could not deserialize public key No such file or directory

user.signingkeyファイル内で~/.gitconfigが正しく設定されている場合は、リポジトリーのディレクトリーから次のコマンドを実行して、リポジトリーレベルで値を確認します。

$ git config user.signingkey

正しい出力の例:

ssh-ed25519 AAAAC3NzaC1IZDI1NTE5AAAAIFIUXAdv5sWOrfZFEPAW8liKjBW3sFxuaNITBWwtFKO

署名鍵が~/.gitconfigで設定した SSH公開鍵でない場合は、リポジトリーにローカルでオーバーライドするものがある可能性があります。

許可された署名者ファイルに関連するエラーが表示された場合

次のエラーメッセージが表示された場合は、許可された署名者ファイルが正しく設定されていることを確認してください。

error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification

このエラーによってコミットログの参照がブロックされることはありません。コミットの信頼性をローカルで検証できなくなるだけです。

SSH署名されたコミットがGit、GitHub、GitLabによって検証されない場合

SSH経由でコミットに署名したにもかかわらず、検証済みとして表示されない場合は、いくつかの原因が考えられます。

コミットCreate者のメールが一致しない

コミット署名は、登録された公開鍵がコミットCreate者のメールと一致する場合にのみ検証済みとして表示されます。GitHubまたはGitLabに登録したメールまたは許可された署名者ファイル内のメールと一致していることを確認してください。

~/.gitconfigに正しいメールアドレスがある場合は、設定がリポジトリーレベルにも正しく反映されているかどうかを確認してください。これを検証するには、リポジトリーのディレクトリーから次のコマンドを実行します。

git config user.email

これが~/.gitconfigで設定した電子メールでない場合は、リポジトリーにローカルにオーバーライドするものがある可能性があります。

公開鍵の設定が間違っている

GitHubでは、SSH鍵設定にアクセスし、ローカルでuser.signingkeyとして設定した鍵が「Signing keys」の下に表示されることを確認します。

GitLabでは、SSH鍵設定にアクセスし、ローカルでuser.signingkeyとして設定した鍵が「Your SSH keys」の下に表示されることを確認します。

ローカルで許可された署名者ファイルの場合は、公開鍵が存在し、電子メールと一致していることを確認してください。

サポートされていないGitクライアントを使用した

ほとんどのGitクライアントはSSHコミット署名をすぐにサポートしますが、例外もいくつかあります。Gitを正しく設定したとしても、SSHコミット署名をサポートしていないGitクライアントでは、コミットは署名されないままになります。

Gitクライアントが最新バージョンであるかどうかも必ず確認してください。

ローカルGitオーバーライド

~/.gitconfigを適切に設定した場合でも、設定がリポジトリーレベルまで正しく伝播されているかどうかも必ず確認してください。

これを検証するには、リポジトリーのディレクトリーから次のコマンドを実行します。

$ cat << EOF $ gpg.format: $(git config gpg.format) $ user.signingkey: $(git config user.signingkey) $ gpg.ssh.program: $(git config gpg.ssh.program) $ commit.gpgsign: $(git config commit.gpgsign) EOF

正しい出力の例:

gpg.format: ssh

user.signingkey: ssh-ed25519 AAAAC3NzaC1IZDI1NTE5AAAAIFIUXAdv5sWOrfZFEPAW8liKjBW3sFxuaNITBWwtFKO gpg.ssh.program: /Applications/1Password.app/Contents/MacOS/op-ssh-sign commit.gpgsign: true

この出力が~/.gitconfigで設定した内容と一致しない場合は、ローカル値を設定解除します。

git config --local --unset gpg.format git config --local --unset user.signingkey git config --local --unset gpg.ssh.program git config --local --unset commit.gpgsign

それでもどこかで間違った値になってしまう場合は、--show-originフラグを使用してその発生元を確認できます。

cat << EOF

gpg.format: $(git config --show-origin gpg.format)

user.signingkey: $(git config --show-origin user.signingkey)

gpg.ssh.program: $(git config --show-origin gpg.ssh.program)

commit.gpgsign: $(git config --show-origin commit.gpgsign)

EOF