Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
GitHub に GPG 公開鍵を登録して Verified マークを表示しようとしたけど今回のユースケースには向いてないので諦めた話

GitHub に GPG 公開鍵を登録して Verified マークを表示しようとしたけど今回のユースケースには向いてないので諦めた話

結局諦めた話になるので Qiita にも書くほどでもないが、それにしては参考URLがたくさん出てきたり、若干の考察もあるのでGistの方に載せます。

3行でまとめ:

  • Windows10, VSCode 1.43.1, Git for Windows 2.25.1 で GPG鍵を生成してcommit時に署名し、GitHubのcommit履歴で Verified を表示できた。
  • GPG鍵は失効対応も含め運用管理で利用者側にリテラシーが求められる = コストが大きい。
  • 複数人のcommitを束ねてpushするような規模であれば、そのcommitが本当に本人によるものかを確認できる署名付きcommitのメリットがコストを上回る。commitする人 = pushする人のような小規模であればコストのほうが大きくなる。今回は後者に該当するため、やらないことにして諦めた。

※以下に記載するリンクURLとタイトルは 2020-03-22 時点のもの。

GitHub用に、Git の commit でGPGによる署名をするには

まずgpgコマンドが必要で、Git for Windows からのbash環境ならgpgコマンドが利用できる。 そのため以下のGitHubヘルプに書かれている通りの手順でGPG鍵を生成して設定すればOK。

ショートカット:

##### 1. 鍵の生成
$ gpg --full-generate-key
gpg (GnuPG) 2.2.19-unknown; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? (defaultを使うのでそのままENTER)

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096 (4096bitにするので4096 -> ENTER)

Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: (なんでも良い)
Email address: (これを git での user.email と同じメールアドレスにする)
Comment:(なんでも良い)
You selected this USER-ID:
    "Real name (Comment) <Email address>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
(パスフレーズ入力)
(...)
gpg: key (...) marked as ultimately trusted
gpg: revocation certificate stored as '/c/Users/xxx/.gnupg/openpgp-revocs.d/(...).rev'
public and secret key created and signed.

pub   rsa4096 2020-03-22 [SC]
      (...)
uid                      Real name (Comment) <Email address>
sub   rsa4096 2020-03-22 [E]

##### 2. 公開鍵のエクスポートとGitHubへの登録
$ gpg --list-secret-keys --keyid-format LONG
/c/Users/xxx/.gnupg/pubring.kbx
-------------------------------------
sec   rsa4096/(key ID) 2020-03-22 [SC]
      (figerprint)
uid                 [ultimate] Real name (Comment) <Email address>
ssb   rsa4096/(subkey ID) 2020-03-22 [E]

$ gpg --armor --export (key ID)
-----BEGIN PGP PUBLIC KEY BLOCK-----
(...)
-----END PGP PUBLIC KEY BLOCK-----

-> GitHub アカウントの Settings -> SSH and GPG keys -> New GPG key にコピペする。

##### 3. 使用する key ID を Git に登録
$ git config --global user.signingkey (key ID)

##### 4. commit時に署名をするには "-S" オプション
$ git commit -S -m ...

##### 5. commit時は常に署名をするには
$ git config --global commit.gpgsign true

VSCode で署名付きcommitをするには

2020-03時点では、以下の構成で簡単にVSCodeから署名付きcommitができるようになった。

  • Windows10
  • Git for Windows 2.25.1
    • git 2.25.1
    • gpg 2.2.19
  • VSCode 1.43.1

設定1: git <> gpg 間をとりもつ gpg-agent 用の設定ファイルを準備

$ cat << EOF > ~/.gnupg/gpg-agent.conf
default-cache-ttl 46000
pinentry-program /usr/bin/pinentry
allow-preset-passphrase
EOF

(念の為 gpg-agent に設定をリロードしてもらう)
$ gpg-connect-agent reloadagent /bye

設定2: VSCode側の preference 設定 (settings.json)

{
    ...
    "git.enableCommitSigning": true,
    ...
}

今回試した範囲では特にトラブル無く署名付きcommitに成功した。 トラブルが発生するとしたらおそらく gpg-agent 周りの可能性が高い。 まず Git for Windows の世界限定で gpg / gpg-agent の動作確認をし、その後 VSCode の git.path が正しく Git for Windows の git を指しているかなどのチェックが必要となるかも。

※設定2 については VSCode の設定画面で設定できる「公式」扱いだが、設定1については後述の参考資料に掲載されていた。

なぜ署名付きcommitを諦めたのか

いくつかの観点で特性やトレードオフを考えてみた。

  1. GitHubのcommit履歴の Verified 表示の特性
    • 公開鍵を削除すると、過去にその鍵でcommitした履歴についても "Unverified" 表示になる。
    • 公開鍵を登録しなおせば、 "Verified" 表示になる。
    • (実際に署名付きcommitをpushして、公開鍵を登録したり削除したりしてみて表示の違いを確認)
  2. Gitで commit に署名するメリットとデメリット
    • メリット
      • commitしてくれた人が(GPGの信頼チェーン的に)信頼できる人かどうか分かる。
      • 特にGitにおいては、複数人からのcommitを束ねてpushする = commitする人とリモートリポジトリにpushする人が異なるケースがあるので、そうした場合にそのcommit内容の正当性確認に有用。
    • デメリット
      • GPG鍵を適切に運用する必要がある。
      • そのgitリポジトリに関わる人達がGPG鍵と署名の仕組みについて理解している(リテラシーがある)状態でないと運用が辛い。
  3. GPGの鍵管理と失効時の処理について
    • PKIと異なり、GPGについては鍵失効の扱いが難しい。
    • gpgの世界では、鍵を作成すると失効証明書も作成され、失効時はそれをimportすることになる。
    • GitHub側の検証では、アカウント設定でのGPG公開鍵登録を削除することになる。(GitHub側はGPGの公開鍵サーバを参照していないぽい)

commitした人とpushする人が異なるかどうかが、コストとメリットの分水嶺になると思われる。

  • commitした人 = pushする人のような小規模なリポジトリであれば、「pushできること」自体がcommitの本人確認となりうる(= GitHubアカウントのhttpsクレデンシャル or SSHキーによるセキュリティ)。
    • このため、わざわざGPG鍵の運用管理コストをかけてまでcommitに署名するメリットは薄い。
  • commitした人 != pushする人のような規模のリポジトリであれば、途中のcommitが正しく本人によるものであることを署名検証で担保できる。
    • このため、GPG鍵の運用管理コストをかけてでもcommitに署名するメリットが大きくなる。

GPG鍵はそもそも運用ルールで自由度が高いが故に、利用者側にリテラシーが求められる傾向を感じる。 このコストがGitの署名付きcommit/tagを運用するメリットと比べてどうか、という点を慎重に判断する必要がありそう。 実際にGit公式でも以下のように書かれている。

タグやコミットに署名を付与するのは素晴らしい試みです。ただし、作業手順のひとつとして採用するのであれば、メンバー全員がやり方を知っているかどうか前もって確認しておくべきでしょう。そうしておかないと、作成済みコミットに署名を付与する方法を説明してまわるハメになりかねません。GPG の仕組み、署名を付与することのメリットをよく理解してから、作業手順に組み込むようにしましょう。

(via: https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E4%BD%9C%E6%A5%AD%E5%86%85%E5%AE%B9%E3%81%B8%E3%81%AE%E7%BD%B2%E5%90%8D )

結論:

  • 今回は commit した人 = push する人となる小規模リポジトリが主な対象であり、動機としても単に「GitHub上でcommit履歴見たとき、"Verified"表示があるとなんかカッコいい」程度のものである。その場合、GPG鍵の運用管理コストがメリットを上回ってしまうと考えられ、署名付きcommitを断念した。

参考URL

Gitの署名:

GitHub と署名:

VSCode と署名付きcommit:

GPG(GnuPG):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment