こんにちは、misty1999です。4月からユニークビジョン株式会社で開発をしています。最近ではLLMツールが発展しており、弊社でもGitHub Copilotを導入したいという声が上がっています。しかし、最も懸念されるのはクレデンシャルが勝手に読み取られ外部に送信されるリスクです。セキュリティ上のリスクも考慮し、次の条件を満たすリポジトリにのみ導入することにしました。
導入条件
- 過去のコミット履歴にクレデンシャルが含まれていない
- 万が一クレデンシャルが含まれるコミット履歴をブランチに作成した場合、運用ブランチにマージできない状態にする
実施したこと
CI導入
GitHub Workflowを使用し、プルリクエスト時にgitleaksでクレデンシャルが含まれているかを自動的にチェックするようにしました。gitleaksはソースコードに潜むクレデンシャル情報を検出するツールです。ワークフローはリポジトリのルート配下の .github/workflows
フォルダに定義されます。今回はこのフォルダ内に ci-gitleaks.yml
というファイルを定義しました。以下はその設定例です。
name: ci-gitleaks
on: pull_request
jobs:
scan:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
この設定は gitleaksの公式リポジトリ のコードを参考にしています。on
は実行条件を意味し、今回は pull_request
でプルリクエストを作成した際にチェックが行われるようにしました。
カスタム設定による除外項目の指定
すべてのクレデンシャルを検知するのではなく、UUIDやシークレットコードのように見えるがマスクされているものに関してはそのままOKにする運用を行います。そのため、以下のような .gitleaks.toml
を配置しました。
[extend]
useDefault = true
[allowlist]
regexTarget = "match"
regexes = [
'''hoge''',
'''HOGE''',
'''oooooo''',
'''OOOOOO''',
'''xxxxxx''',
'''XXXXXX''',
'''EXAMPLE''',
'''example''',
# UUID
'''[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}''',
]
useDefault = true
で既存の設定に加えるよう指定し、allowlist
で許可する表現を指定しています。具体的には、regexes
にマッチするような表現が含まれる行はクレデンシャルではないものと見なします。これにより、UUIDやシークレットコードの一部表現を変えたものはCIで引っかからないようになります。
クレデンシャルの排除
現在のコードに含まれるクレデンシャルの排除
これらは環境変数に逃すか、使用していないなら削除する必要があります。
過去のコミット履歴からクレデンシャルを排除
ローカルにgitleaksを導入し、gitleaks detect -v
を実行すると過去のクレデンシャルの一覧が表示されます。このうち対応が必要な部分については、git-filter-repoを用いて先行記事に従って作業することでコミット履歴を削除できます。ただし、次の2点に注意が必要です。
- コミット履歴を変更するため、作業中の人には全員一度ブランチにpushしてもらう。コミット履歴の変更後は
git fetch origin
とgit reset --hard origin/develop
を実行し、ローカルとリモートでコミット履歴に不整合がない状態にしてもらう。 - 運用ブランチがprotectedで保護されている場合、adminの権限を持っている人に作業してもらうか、一時的にprotectedを外してforce pushを許可してもらう必要がある。
まとめ
.gitleaks.toml
の useDefault = true
設定を使えば、自分でカスタムに例外を設定できて非常に便利です。セキュリティ上の懸念がありGitHub Copilotの導入に踏み切れない場合、この記事が参考になれば幸いです。