Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

GitHub에서 커밋에 서명하기

최근에 GitHub에 GPG 사인을 표시해 주는 기능이 추가되었다. Git에서 커밋을 GPG로 서명하는 기능이 있다는 것은 알고 있었지만 실제로는 한 번도 사용해 본 적이 없고 사용해야겠다고 느껴본 적도 없다. 하지만 GitHub에 GPG 사인을 검증해주는 기능이 들어가니까 써봐야겠다는 생각이 들었다.

먼저 GPG 사인이 왜 필요한가 생각해 보면 보통 Git을 사용할 때 ~/.gitconfig 파일에 다음과 같이 이메일과 사용자 이름을 설정한다.

[user]
  email = outsideris@gmail.com
  name = Outsider

설정을 하고 나면 이후부터 커밋할 때 author에 이 정보를 사용한다. 자연스러운 동작이지만 웹서비스에 가입할 때 이메일을 인증하는 것과 같은 과정이 없으므로 아무 이메일 주소를 넣어도 상관이 없다. 이는 이메일 주소로 표시되는 사람과 실제 커밋을 한 사람이 다른 사람일 수도 있다는 의미가 된다. 보통은 이메일이 GitHub의 계정에 등록되어 있고 내가 한 작업을 알리기도 쉽지 않은데 굳이 다른 사람이 한 것처럼 할 필요가 없으므로 굳이 커밋에 서명까지 해야 할 이유가 크게 다가오지 않는 것도 사실이다. 하지만 이메일 주소는 상황에 따라 바뀔 수도 있고 GPG로 서명을 하면 실제로 자신이 커밋을 했다는 것을 다른 사람이 검증할 수 있다. 프로젝트를 사용하는 처지에서 생각해 보면 커밋과 태그에서 서명할 수 있으므로 다른 사람의 코드를 받거나 할 때 위조되거나 잘못된 코드를 받지 않는다는 것을 검증할 수 있다. 보통은 GitHub를 신뢰하므로 그 역할이 아주 강력하지는 않지만, Git이 GitHub만을 위한 것은 아니므로 서명을 하는 건 괜찮아 보인다.

왜 꼭 해야 하는가? 라고 하면 애매할 수도 있으므로 GitHub에서 지원하므로 굳이 안 할 이유도 없어서 앞으로는 서명을 하기로 했다.

GPG 서명

Git에서 서명을 할 때 비밀키는 본인만 갖고 있으므로 다른 서명인증과정과 똑같이 GitHub에 공개키를 등록해 놓고 비밀키로 커밋을 서명하면 공개키로 내가 서명했는지를 검증하는 것이다. 비밀키/공개키 방식에 따라 당사자가 비밀키를 유출하지 않는 한 공개키로 풀 수 있는 사인을 만들 수 있는 사람은 본인밖에 없다. GPG 서명과 관련해서는 GitHub 문서에 잘 나와 있다.

GPG 키 목록 확인

$ gpg --list-keys
/Users/outsider/.gnupg/pubring.gpg
----------------------------------
pub   4096R/131EA9B1 2015-01-10 [expires: 2025-01-07]
uid       [ultimate] JeongHoon Byun <outsideris@gmail.com>
uid       [ultimate] outsider <outsider@keybase.io>
sub   4096R/285ADBCB 2015-01-10 [expires: 2025-01-07]

기존에 생성한 GPG 키가 있는지는 gpg --list-keys 명령어로 확인할 수 있고 위처럼 등록된 키가 나온다. 없으면 새로 생성해야 하는데 나 같은 경우는 전에 홍민희님이 소개해 준 Keybase를 이용해서 내가 사용하는 서비스를 인증할 때 GPG 키를 생성해 놓은 게 있어서 그대로 사용했다.

Git 커밋에 서명하기

Git에서 커밋을 할 때 서명을 하려면 -S 옵션을 다음과 같이 사용하면 된다. 처음에 시도하면 signing failed: No secret key라면서 키를 지정하지 않았다고 오류가 나오는데 전역 설정파일인 ~/.gitconfig에 다음과 같이 등록하면 된다.

[user]
  email = outsideris@gmail.com
  name = Outsider
  signingkey = 131EA9B1

user 부분에 signingkey로 앞에서 확인한 GPG의 ID를 등록한다. 이제 커밋할 때 -S 옵션을 주면 커밋에 서명을 추가한다.

git ci -S --amend

You need a passphrase to unlock the secret key for
user: "JeongHoon Byun <outsideris@gmail.com>"
4096-bit RSA key, ID 131EA9B1, created 2015-01-10

[master 9d63fa3] Initial commit
 Author: JeongHoon Byun (aka Outsider) <outsideris@gmail.com>
 Date: Sat Apr 9 21:03:06 2016 +0900
 4 files changed, 74 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 LICENSE
 create mode 100644 README.md
 create mode 100644 package.json
 ```

 서명이 정상적으로 됐다. Git에서 커밋 히스토리를 볼 때 `--show-signature` 옵션을 사용하면 서명을 함께 볼 수 있다.

 ```bash
 $ git log --show-signature
 commit 9d63fa32eb83279ef20f38b10cf9e72634b06621
gpg: Signature made 토  4/ 9 21:43:31 2016 KST using RSA key ID 131EA9B1
gpg: Good signature from "JeongHoon Byun <outsideris@gmail.com>" [ultimate]
gpg:                 aka "outsider <outsider@keybase.io>" [ultimate]
Author: JeongHoon Byun (aka Outsider) <outsideris@gmail.com>
Date:   Sat Apr 9 21:03:06 2016 +0900

    Initial commit

GitHub의 GPG 서명 표시

이제 GitHub에서 서명이 잘 표시되도록 공개키를 GitHub에 등록해야 한다. GitHub에서 Settings의 SSH and GPG keys 메뉴에 가면 아래와 같이 GPG의 공개키를 등록할 수 있다.

GitHub에 등록된 GPG 공개키

키를 등록하고 서명한 코드를 GitHub 저장소에 푸시하면 Verified 표시를 볼 수 있다.

GitHub의 커밋에 Verified가 표시됨

커밋할 때마다 -S 옵션을 주는 것 불편하므로 항상 서명을 하도록 git config --global commit.gpgsign true를 실행하거나 ~/.gitconfig 파일에 다음 내용을 추가할 수 있다.

[commit]
  gpgsign = true
2016/04/21 02:35 2016/04/21 02:35