🙆

そのマシンユーザー不要ですよ!GitHub Appsを使ってGitHub Actionsを利用しよう

2021/12/06に公開

はじめに

こんにちは!Hamee株式会社の tatsuo48 です。
GitHub ActionsにはデフォルトでGITHUB_TOKENというシークレットが存在しており、環境変数にセットして利用することで、Actionsがトリガーされたリポジトリに対する操作が可能です。
GITHUB_TOKENシークレットについて

これはこれで便利なんですが、特定の条件のときに少し問題があります。

CIの中で別リポジトリを使いたいときどうする問題

上記の通り、GITHUB_TOKENでは権限の範囲がActionsがトリガーされたリポジトリに制限されます。よって以下のようなユースケースには適しません。

  • CIの中で別のプライベートリポジトリを参照したい
    • Terraformのプライベートモジュールとか

こういった場合、マシンユーザという人に紐付かないユーザを作り、そのユーザの個人アクセストークンが使われたりすると思います。
GitHubも規約上でマシンユーザを容認しています。
3. アカウントの要件

コンピュータアカウントとは、「アカウント」に代わって「規約」を受け入れ、有効なメールアドレスを提供し、その動作について責任を負う人間個人により設定された「アカウント」のことです。 コンピュータアカウントは、自動化されたタスクを実行するためにのみ用いられます。 コンピュータアカウントの動作は複数のユーザが指示できますが、コンピュータの動作について究極的な責任を負うのは「アカウント」の所有者です。 無料の「ユーザアカウント」に加えて、無料のコンピュータアカウントを複数保持することはできません。

お手軽だし、規約上も問題なくマシンユーザを作ることはできますがいくつかデメリットもあります。

  • トークンの有効期限管理
    • 発行した個人アクセストークンを無期限にしない場合、トークンの有効期限切れの都度入れ替え作業が発生します。
  • ユーザ課金の発生
    • マシンユーザといえど、ユーザです。GitHubのシート消費があるのでその支払いも必要です。

これらのデメリットを解消する方法として GitHub Appsの利用があります。
GitHub Appsを利用すると

  • トークンの有効期限管理
    • 発行後、短時間で利用できなくなるので考えなくて良くなる
  • ユーザ課金の発生
    • ユーザではないのでシート消費が発生しない

というように良いことづくめです。
以降では、GitHub Appsとその使い方、設定方法について説明します〜

GitHub Appsとは

とりあえず公式docをぺたり。
GitHub Apps

GitHub Appsとはなんぞや?というのはこちらの記事がわかりやすかったのでご参考にどうぞ!
作って学ぶ GitHub Apps

従来のOAuth Appsはユーザに対してインストール - ユーザが削除されたりリポジトリへの権限を失うと消える - アクセストークンはユーザが取り消さない限り永久有効。
それとは違いGitHub Appsはリポジトリに対してインストール - 正確にはリポジトリのオーナー(OrganizationやUser)に インストールして、配下のリポジトリに付与するようなイメージ。
簡単に言うとOAuth Appsはユーザ単位のアプリで、GitHub Appsはリポジトリ単位のアプリとなる。

というのが簡潔でわかりやすかったです。

構築する統合の決定にある図も温かみ溢れる図でわかりやすいですね。

ということで次は実際にどんなふうにGitHub ActionsにGitHub Appsを設定するの?というところを話します。

やりかた

GitHub Appsを作る

https://github.com/organizations/{{org名}}/settings/apps
にアクセスしてアプリを作成します。
GitHub App nameはアプリの名前をつけてあげて下さい。
Homepage URLは適当でOKです。
WebhookActiveのチェックを外してあげてください。
権限は必要なものをつけていきます。
git cloneしたい場合はRepository permissionsContentsRead以上にします。

GitHub Appをインストールする

https://github.com/organizations/{{org名}}/settings/apps/{{app名}}
にアクセスしてGenerate a private keyを押して秘密鍵を作ります。
この秘密鍵を使ってCIの中で一時トークンの発行をするので大切に保管してください。
また、AppIDもメモしておきます。

https://github.com/organizations/{{org名}}/settings/apps/{{app名}}/installations
にアクセスしてアプリのインストールをします。
リポジトリの選択ではアクセスを許可するリポジトリを指定します。

リポジトリの許可はインストール後に以下のリンクからも変更できます。
https://github.com/organizations/{{org名}}/settings/installations/{{AppID}}

シークレットを設定

以下の2点をCIの対象リポジトリのシークレットに指定します。
https://github.com/{{org名}}/{{リポジトリ名}}/settings/secrets/actions

  • 先ほど作成した秘密鍵
  • AppID

CIの中でトークンの発行をする

ここまでできたら後はCIの中で利用するだけ!
秘密鍵とAppIDから一時トークンを発行する作業は、以下のActionsを使えば簡単にできます。
https://github.com/marketplace/actions/create-github-app-token
※以前は非公式なActionsしかなかったのですが、今は上記の公式なActionsがあるので使いましょう。
情報提供ありがとうございます!: https://docs.google.com/presentation/d/10-HgSST2xR5H3xCwGLKCk_PBwq4zHcxD2393ifwOsiM/edit#slide=id.g2608d78f5c0_0_585

こんな感じです。

jobs:
  job:
    runs-on: ubuntu-latest
    steps:
      - name: Generate token
        id: generate_token
        uses: actions/create-github-app-token@v1
        with:
          app-id: ${{ secrets.APP_ID }}
          private_key: ${{ secrets.PRIVATE_KEY }}
      - name: Use token
        env:
          TOKEN: ${{ steps.generate_token.outputs.token }}
        run: |
          echo "The generated token is masked: ${TOKEN}"

おまけ

GitHubActionsアドベントカレンダーなんですが、おまけでCircleCIの場合の使い方も載せておきます。
トークン発行を自前でするのが面倒なので、以下のツールを使わせてもらっています。ありがとうございます。
https://github.com/mackee/git-credential-github-apps

jobs:
  first:
    executor: hogehoge
    steps:
      - checkout
      - run: |
          wget https://github.com/mackee/git-credential-github-apps/releases/download/v1.1.1/git-credential-github-apps_1.1.1_Linux_x86_64.tar.gz 
          tar -zxvf git-credential-github-apps_1.1.1_Linux_x86_64.tar.gz
          chmod 755 git-credential-github-apps
          mv git-credential-github-apps /usr/bin/git-credential-github-apps
      - run: |
          echo -e $PRIVATE_KEY > /tmp/key.pem
          export $(echo -e 'host=github.com\nprotocol=https' |  git-credential-github-apps -privatekey /tmp/key.pem -appid $APP_ID -login {{org名}} get | grep password)
          export GIT_TOKEN=$password

おわりに

いや〜、結構設定が手間ではありますね。
必要な権限の問題などでマシンユーザやOAuth Appsが適していることもあると思うのでバランスをみながら上手に使っていきたいですね![1]
GitHub Actions Advent Calendar 2021、7日目の明日はkt15さんの「最近公開した自作 Action について」です!

脚注
  1. GitHub App と OAuth App の違い ↩︎

Discussion