🔑

GithubActionsでPrivateリポジトリへアクセスするときのキーをなくせ

2024/03/14に公開

こんにちは、インフラ・SREチームのよしたくです。
技術負債の解消を進めているのですが、その取り組みの一部であるキーレス化を紹介します。

鍵の管理人をやっていられるか

AWSのIAMユーザーやGCPのサービスアカウントのキー、GithubのPersonalAccessTokenなど、
呼び方や種類はさまざまあれど、要はそのユーザーやアカウントになりきることができる鍵は広く使われているのではないでしょうか。

ところでそれらの鍵が外部に流出してしまったら大変ですね。強い権限を持つ鍵の場合は、社内でもアクセス制限されているメンバーにわたったら、悪用されかねないです。
このような鍵の流出時の責任を問われるのは管理人です。

―――――そのようなリスクの伴う鍵の管理人をやりたいでしょうか―――――

・・・普通はやりたくないですよね、10万もらってもやりたくないです。100万積まれても・・・100万なら考えます。
冗談はさておき、古くから運用しているシステムではキーが使われていることが多いかと思います。おそらく開発者中心にローテーションや権限などの管理をしていることがおおいので、鍵が多ければ多いほどこの運用は大変になりますね。

弊社も上記の状況でありますが、キーレス化しやすいところから徐々に数を減らす取り組みを行っています。

削除対象

今回はGithubのPersonalAccessToken(以下PAT)を削除してみましょう。

弊社では全サービスに共通するTerraform moduleは独立したプライベートリポジトリに管理して使用しています。

module "this" {
  source = "git@github.com:myOrganization/common-modules.git//terraform/aws/vpc?ref=zzz"
}

またplan/applyをGithubActionsで回しています。
ただ、上記のコードをそのまま実行しようとすると、terraform initの段階で参照できないよーと怒られてしまいます。

Initializing modules...
Downloading git::https://github.com/myOrganization/common-modules.git//terraform/aws/vpc?ref=zzz for my-module...
╷
│ Error: Failed to download module
│ Could not download module "my-module" (main.tf:1) source code

初期段階では、組織内のプライベートリポジトリに権限のあるPATを作成し、これをActionsに埋め込むことで解決しました。

- id: set-token
  run: |
    git config --global url."https://x-access-token:${{ secrets.PAT }}@github.com/myOrganization/".insteadOf "ssh://git@github.com/myOrganization"
- id: run
  run: |
    terraform init
    terraform plan -lock=false -no-color

ただし、PAT運用をしていると、以下のような問題に直面します。(ほかの鍵でもほぼ同じです)

  • PATは誰が管理するのか
  • 特定の個人が発行している、その人がいなくなったらどうするのか
  • 気づいたらPATの期限が切れていてActionsが失敗する、昨日まで動いていたのになぜ、という事象が起こり得る

ということで、PAT運用を続けることは好ましくなく、次の手段を用いて鍵の削除を行います。

GithubAppを使う

GithubAppを使うことで、PATの代わりに短時間だけ有効なキーを発行することが可能です。Settingsからの作成となるので、Organizationの場合はOwnerに作成を依頼する必要があります。
そして、このGithubAppを利用してキーを発行するstepを追加してあげるだけです。ちょっと検索するだけでも結構な数のアクションがありますね。弊社では最もStarの多いアクションを利用しています。

## ここを追加
- id: generate-token
  uses: tibdex/github-app-token@3eb77c7243b85c65e84acfa93fdbac02fb6bd532 # tag=v2.1.0
  with:
    app_id: ${{ secrets.github-app-id }}
    private_key: ${{ secrets.github-app-private-key }}
- id: set-token
  run: |
    git config --global url."https://x-access-token:${{ steps.generate-token.outputs.token }}@github.com/myOrganization/".insteadOf "ssh://git@github.com/myOrganization"
- id: run
  run: |
    terraform init
    terraform plan -lock=false -no-color

That's All!!
かなり簡単に鍵を取り除くことができましたね。

まとめ

今回のポイントは、
「別のプライベートリポジトリにアクセスするためのキーとしてPATを使っていたところを、GithubAppで一時的なトークンを払い出して利用する」
ように変更した点です。
すなわち「別のプライベートリポジトリにアクセスするキー」が必要な場合は今回のケースと同様の対処でキーレス化が可能ということですね。
社内プライベートリポジトリでgo modulesを管理している場合なんかが一例です。

本記事のようなキーレス化をはじめとした負債解消進めたいんだ、というかたはぜひ採用ページをご覧ください。

https://coconala.co.jp/recruit/engineer/

Discussion