tweeeetyのぶろぐ的めも

アウトプットが少なかったダメな自分をアウトプット<br>\(^o^)/

【git】GnuPG x git-secretでcredentialなどの秘匿情報を含むファイルを暗号化して安全にcommitする - その2: 複数人で扱う場合

はじめに

gitやgithubでcredentialやtokenなどの秘匿情報を含むファイルを暗号化してcommitするメモを書きました。

今回は、それを複数人であつかう場合のメモです。

アジェンダ

1. ながれのイメージ

流れを単純にしたくて図を書いてみました。
説明は図にお任せでご参考あれ。

f:id:tweeeety:20210510020507p:plain

ということで、以降は上記の図のに沿って説明します。

出てくる人はこんな2人のイメージ。

  • Aさん: 既存リポジトリ担当者
  • Bさん: 新規メンバー

また、Aさん、BさんともにMac環境でgpggit-secretはインストール済みの想定です。
インストールに関してはコチラをご参考ください。

2. [Aさん] 秘匿情報をgit secret管理化にする

gpgでkeyの生成

$ gpg --gen-key

gpg (GnuPG) 2.3.1; Copyright (C) 2021 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.

注意: 全機能の鍵生成には "gpg --full-generate-key" を使います。

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: A-san
電子メール・アドレス: a-san@example.com
次のユーザIDを選択しました:
    "A-san <a-san@example.com>"

~ 省略 ~ 

リポジトリを用意する

この記事のサンプル用に、
ユーザAさんとBさん想定のためgit configでnameとemailを登録しておきます。
また、暗号化したい秘匿情報を含むファイルをbasic.yamlとして作ります。お手元の任意のファイルに置き換えて読んでください。

すでに運用されてるリポジトリではここは行わなくても大丈夫です。

# 既存リポジトリをclone
# [sample repo]はリポジトリのurlに置き換えてください。
$ git clone [sample repo]

# gitのnameとemailを設定
$ git config user.name "A-san"
$ git config user.email a-san@example.com

# 暗号化する秘匿情報を含むファイルを作成済みのてい
$ cat basic.yaml
BASIC_AUTH_ID: "hogehoge"
BASIC_AUTH_PW: "fugafuga"

git-secret管理化にする

リポジトリをgit−secret管理化にします。

# git-secret管理化にする
$ git secret init

# まだ誰も登録されてない事を確認
$ git secret whoknows
git-secret: abort: no public keys for users found. run 'git secret tell email@address'.

# git-secretに自身の権限を付与
$ git secret tell -m
gpg: keybox'/Users/tweeeety/github/git-secret-sample-02/.gitsecret/keys/pubring.kbx'が作成されました
gpg: /Users/tweeeety/github/git-secret-sample-02/.gitsecret/keys/trustdb.gpg: 信用データベースができました
git-secret: done. a-san@example.com added as user(s) who know the secret.

# 自分が登録されてることを確認
$ git secret whoknows
a-san@example.com

# 暗号化するファイルの登録
$ git secret add basic.yaml

git push する

$ git status
On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore
    .gitsecret/
    basic.yaml.secret

$ git add .
$ git commit -m 'add git-secret sample'
$ git push origin main

3. [Bさん] gpg keyの作成&エクスポート

gpg keyの作成&エクスポート

gpg keyを作成してエクスポートします。
エクスポートした公開会議はAさんにファイル共有などで渡します。

$ gpg --gen-key
gpg (GnuPG) 2.3.1; Copyright (C) 2021 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.

注意: 全機能の鍵生成には "gpg --full-generate-key" を使います。

GnuPGはあなたの鍵を識別するためにユーザIDを構成する必要があります。

本名: B-san
電子メール・アドレス: b-san@example.com
次のユーザIDを選択しました:
    "B-san <b-san@example.com>"

$ gpg --list-keys
/Users/tweeeety/.gnupg/pubring.kbx
----------------------------------
pub   ed25519 2021-05-09 [SC] [有効期限: 2023-05-09]
      3E34718C10CA6CAC878459D286823EB8769B15F9
uid           [  究極  ] B-san <b-san@example.com>
sub   cv25519 2021-05-09 [E] [有効期限: 2023-05-09]

# エクスポート
$ gpg -o B_san_key.pub --export B-san

エクスポートした鍵(B_san_key.pub)は、ファイル共有やメールなどでAさんに渡します。

この時点で復号化を試してみる

当然できないのですが、できないことを確認してみます。
まず最初に、擬似的に複数人の想定用のサンプルとしてuserとemailも変えていいます。

# リポジトリの取得と設定を行う
$ git clone [sample repo]
$ git config user.name "B-san"
$ git config user.email b-san@example.com

次に git secretで復号化できるかを試します。

# 復号化できない確認
$ git secret cat basic.yaml.secret
gpg: 公開鍵の復号に失敗しました: No secret key
gpg: 復号に失敗しました: No secret key
git-secret: abort: problem decrypting file with gpg: exit code 2: /Users/tweeeety/github/git-secret-sample-02/basic.yaml.secret

# 権限の付与もできない
$ git secret tell b-san@example.com
git-secret: abort: no key found in gpg user keyring for: b-san@example.com

以下のことがわかります。

  • git secret cat: public keysにuserがいないので復号化できない
  • git secret tell: GPGにemailが登録されてないのでアクセス権を与えることはできない

4. [Aさん] GPGとgit-secretにBさん情報を設定

Bさんからエクスポートした鍵を受け取っておきます。

主に以下の3点を行います。

  • GPGにB -san鍵をインポート
  • git-secretにBさん権限の付与
  • git-secretで新たに暗号化

GPGにB -san鍵をインポート

# インポート前に確認
$ gpg --list-keys
/Users/tweeeety/.gnupg/pubring.kbx
----------------------------------
pub   ed25519 2021-05-08 [SC] [有効期限: 2023-05-08]
      6CC788FE396E2487410953356499DF1CBBB499CF
uid           [  究極  ] A-san <a-san@example.com>
sub   cv25519 2021-05-08 [E] [有効期限: 2023-05-08]

# Bさんの鍵をインポート
$ gpg --import B_san_key.pub
gpg: 鍵606D84736C69D687: 公開鍵"B-san (create sample gpg-key) <b-san@example.com>"をインポートしました
gpg:           処理数の合計: 1
gpg:             インポート: 1

# インポートされた確認
$ gpg --list-keys
/Users/tweeeety/.gnupg/pubring.kbx
----------------------------------
pub   ed25519 2021-05-08 [SC] [有効期限: 2023-05-08]
      6CC788FE396E2487410953356499DF1CBBB499CF
uid           [  究極  ] A-san <a-san@example.com>
sub   cv25519 2021-05-08 [E] [有効期限: 2023-05-08]

pub   rsa1024 2021-05-08 [SC]
      18ECA6436499ADF3A0598B00606D84736C69D687
uid           [  不明  ] B-san (create sample gpg-key) <b-san@example.com>
sub   rsa1024 2021-05-08 [E]

git-secretにBさん権限の付与

GPGのBさん鍵を追加したら、git-secretでBさんの権限を付与します。

# この時点の登録を確認
$ git secret whoknows
a-san@example.com

# Bさんにアクセス権を与える
$ git secret tell b-san@example.com
git-secret: done. b-san@example.com added as user(s) who know the secret.

# 確認するとBさんが追加されている
$ git secret whoknows
a-san@example.com
b-san@example.com

git-secretで新たに暗号化

リポジトリにはAさん、Bさんの公開鍵で暗号化したファイルをあげる必要があります。
そこで、一度、復号化してから再度暗号化を行います。

# 暗号化されたbasic.yaml.secretしかない
$ ll
total 32
drwxr-xr-x   8 tweeeety  staff   256  5  9 06:40 .
drwxr-xr-x  39 tweeeety  staff  1248  5  8 22:38 ..
drwxr-xr-x  12 tweeeety  staff   384  5  9 03:27 .git
-rw-------   1 tweeeety  staff    11  5  8 22:53 .gitignore
drwxr-xr-x   4 tweeeety  staff   128  5  8 22:49 .gitsecret
-rw-rw-r--   1 tweeeety  staff   684  5  9 05:24 B_san_key.pub
-rw-r--r--   1 tweeeety  staff    23  5  8 22:39 README.md
-rw-r--r--   1 tweeeety  staff   214  5  8 22:55 basic.yaml.secret

# 一度復号化
# basic.yamlができている
$ git secret reveal
git-secret: done. 1 of 1 files are revealed.

# 再度、暗号化することで
# Aさん、Bさんの鍵で暗号化される
$ git secret hide -d
git-secret: done. 1 of 1 files are hidden.

git push

リポジトリに追加します。

$ git commit -a -m 'add B-san to git-secret'
$ git push

4. [Bさん] 暗号化された秘匿情報ファイルを復号化

暗号化された秘匿情報ファイルをgit pullします。

以下のいずれかで復号化できることが確認できます。

  • 確認のみ: git secret cat 暗号化されたファイル
  • 復号化: git secret reveal
# pushされた暗号化ファイルをgit pull
$ git pull

# 確認
$ git secret cat basic.yaml.secret
BASIC_AUTH_ID: "hogehoge"
BASIC_AUTH_PW: "fugafuga"

# 復号化
$ git secret reveal

サンプル

中身は特にないですがサンプル リポジトリはこちら。

おわりに

git secretを複数人で使う想定でためしたく、
手元のMacの他にLinux/VPSを用意しましたがGPGのversionがあわずに断念…。

使ってないMacBook Proをひっぱりだして試しました。

MacとLinuxで行う場合はGPGのversion合わせるのがわりと時間がかかる、ということがわかってよかった……
のか?w