🔒

Secretiveを使用した署名付きCommit

に公開
4

なぜコミットに署名をするのか

そのコミットが本当に本人が作ったかどうかを判断出来るようにする為です。
コミットに署名をする事で以下のようなことを防ぐことができます。

  1. なりすまし防止
  2. 改竄の検知
  3. プロジェクトの信頼性向上

コミットに署名されているとGitHubに以下のように表示されます↓

かっこいい!!!!!!!!!!(重要)

Secretiveのメリット

通常コミットに署名する場合、パスフレーズを毎回入力したりしなければならないので、少し不便です。
そこで、Secretiveを使用することで、TouchIDを使用して署名できるようになるので、かなり楽になります。鍵の管理なども簡単になるのでおすすめです。

Secretiveのインストール

https://github.com/maxgoedjen/secretive
Homebrewを使用して簡単にインストールできます。

brew install secretive

Secretiveの起動

インストールされると現時点では/Applications/Secretive.appにアプリが配置されるのでそれを開きます。

open /Applications/Secretive.app

初回起動時は以下のような画面になります。

上から順番にチェックをつけていけばセットアップは完了です。

Secretiveで鍵の作成

初回起動時の連携の設定を開くと連携できるものが表示されるので、
Gitの署名を開き、シークレットを新規作成をクリックします。
鍵の種類はecdsa-sha2-nistp256が使用されます。
作成すると以下のように表示されます↓

Gitの設定

次に作成した鍵を使用して署名するよう設定します。
Gitの署名タブにも設定が表示されているので、それに従いながらやっていきます。

~/.gitconfigの設定

皆様お好きなエディタvimを使用して開きます。

vim ~/.gitconfig

追加する設定は以下です。(実際にはSecretiveに表示されているもを参照してください)
既に同じ項目で設定が記述されていれば追記する形で追加します。

[user]
    # 公開鍵のパスを設定
    signingkey = /Users/user/Library/Containers/com.maxgoedjen.Secretive.SecretAgent/Data/PublicKeys/{公開鍵名}.pub
[commit]
    # gpgsignを有効化
    gpgsign = true
[gpg]
    # ssh鍵による署名
    format = ssh
[gpg "ssh"]
    # allowedSignersFileのパス
    allowedSignersFile = ~/.gitallowedsigners

~/.gitallowedsignersの設定

.gitallowedsignersは任意の名前、場所に設定できます(.gitconfigで場所の指定が可能な為)
Secretiveに表示されている~/.gitallowedsignersの設定をそのまま記述します。

echo "integrations_configure_using_email_placeholder {公開鍵の中身}" > ~/.gitallowedsigners

環境変数の設定

環境変数のSSH_AUTH_SOCKを使用してエージェントを経由する必要があるので設定します。
自身の使用しているシェルの設定に追記します。
エージェントのパスはSecretiveの画面から取得できます。

ソケットのパスをコピーして環境変数へ設定します。

echo 'export SSH_AUTH_SOCK={socket.sshのパス}' >> ~/.zshrc
source ~/.zshrc

GitHubへ公開鍵の登録

今のままではまだGitHubがユーザーの公開鍵を知らないので、登録してあげる必要があります。

以下にアクセスし、公開鍵を登録します。
https://github.com/settings/ssh/new
Key typeSignin Keyに変更して、公開鍵を設定してAdd SSH keyを押下。

コミットしてみよう!

実際にコミットをしてみます。
テストでコミットする場合は以下のようにからのコミット作成するのがおすすめです。

git commit --allow-empty -m "empty commit"

すると、Secretiveが署名のためにTouchIDを求めてきます。

そして、これを承認するといつも通りコミットが作成されます。

実際にプッシュして、コミットを確認すると・・・・

無事に認証されてました🎉🎉🎉

まとめ

Secretiveを使用することでパスフレーズを入力するめんどくさい工程や、鍵の管理を省きつつ、
コミットの署名をすることで、プロジェクトの信頼性を向上させることができました!
これで、悪意のあるコミット(なりすましコミット)を見分けれるようになったので安心です。
よければ皆さんも試してみてください!!

GitHubで編集を提案

Discussion

rakiraki

これで、悪意のあるコミットを見分けれるようになったので安心です。

たぶん安心できないよ。攻撃者も署名してるかもしれないし。

署名ってのは単にこの鍵を持っている人がソレの所有者を名乗っているぜ、そしてそれは(ここではgithubでは)正しいと思うぜ、ってだけでしかない。
俺がこう署名したら俺ってことだぜをgithubに教えているから、その署名(サイン)がしてあったらgithubはお前(俺)か、って思うだけなので、Verified されているから安心、なんてことにはならない。
単に署名している人がコミットしただけ。

世の中的にもしてない人のほうが多いと思われ、
https://www.reddit.com/r/git/comments/1bwcdyl/do_you_sign_your_commit/?tl=ja

署名していないから信頼できない、ではないし、
署名してあるから信頼できる、でもない。

元ネタ込みで詳しい話はここがいいと思う。よく読もう。
https://ama.ne.jp/post/git-signing/

なおいどなおいど

おっしゃる通り

これで、悪意のあるコミットを見分けれるようになったので安心です。

これは誇張しすぎな表現でした、、すみません。

ですが、コミット署名はなりすましコミットには十分に効果を発揮すると考えています。
署名されていないコミットは、コミット時のメールアドレスを他人のものにするだけで、簡単になりすますことが可能です。
これにより、悪意のあるコミットが外部からプッシュされると、そのなりすまされた本人がコミットしたように表示されます。そこで、コミット署名をしておくとコードの出所をある程度保証できます。

もちろん、GitHubアカウントがそもそも乗っ取られていたり、秘密鍵が流出している場合この効果はなくなりますが、なりすます難易度が桁違いになると思います。
昨今のサプライチェーン攻撃などでもコミットがなりすまされていたという事例があったので、署名するだけで防げるのなら、しないよりは何倍も安全になると思います。
もちろんその署名が100%安全だとは言えませんが、署名なしよりは十分信頼に足るコミットになるのではないでしょうか。

ご教示いただいたリンク先のタグに署名するというのは初めて知ったので、詳しく調べてみようと思います!ありがとうございます!

rakiraki

そこで、コミット署名をしておくとコードの出所をある程度保証できます。

できないよ。

署名なしよりは十分信頼に足るコミットになるのではないでしょうか。

ならないよ。

ホモグラフ攻撃対策と同じで、verified されていてもアカウントをチェックして、そのコミットが本当に知人のものかどうかを確認しないと信頼はできない。
なりすましアカウントが署名していて、アカウントチェックを怠ったら、なりすましアカウントのコミットを間違って信頼しちゃうよ?

user-1 と user‐1 の区別を目視でつけられるだろうか?(ハイフンの文字種が違う)

この2つのアカウントが両方とも署名していたら、github 上は両方とも verified と表示される。
--show-signature しても検査値が違うことに気付けないケースも多々ある(並べて見るとかしないとそうそう他人のGPGキーの値なんか覚えてない)し、なりすまし対策が難しい要因でもある。

git の署名は、署名をしたAさんがいて、この内容はAさんが署名したものに間違いない、としか言ってない。
AさんA'さんA+さんの区別はユーザー側がつける必要がある(verifyする必要がある)。
GitHub 上の verified はこの点でほぼ役に立たないし、ローカルの git で常に verifiy するのも現実的じゃない。
verify していない署名付きコミットの価値は、署名なしコミットと(なりすまし対策として)さほど変わらない。
なので、先の記事でもコミットじゃなくタグに署名しろと言われている。(タグベースなら署名の都度チェックも負担にならないし、署名した人のファクトチェックもできるだろ、という話)

なおいどなおいど

確かに、プライベートなリポジトリでもホモグラフ攻撃的な感じで偽装されたら見分けが難しいですね・・・🤔厳格にするならCIでユーザーを確認などの処理を入れるなど対策できそうですが(CIが改竄されるリスクはどうなんだ的な問題は出てきそうですが・・・)、タグベースならより人間の手でも確認できそうです、、!
非常に勉強になりました、ありがとうございます🙏