🐟

Github Appのインストール時にstateを指定する

2023/04/05に公開

Github App

Github Appをインストールする最大のメリットは、個人へのインストールだけではなく、組織にインストールできるため、アクセストークンにまつわる問題を取り払う事が出来ます。分かりやすいアクセストークン関係の問題では、社員退職に伴ったアクセストークンの無効が、稼働するシステムへの影響を及ぼすなどです。どこに退職社員個人のアクセストークンを使っていたかを把握して、入れ替える作業を行います。手間以上に、違う社員個人のトークンに入れ替えるため、同じ課題を抱えたまま運用を続けることになります。

Github Appは、審査を経てマーケットプレイスに掲載可能なアプリですが、掲載はマストではありません。自社のニーズに応じて自社でインストールを促すことも出来るので、柔軟な配信が出来ます。

https://docs.github.com/ja/apps/creating-github-apps/creating-github-apps/differences-between-github-apps-and-oauth-apps

アプリのインストールリンク

アプリ自体は、公開状態であれば誰でもインストールできます。
Make public

インストールURLのベースは、以下のPublic Linkです、
Github app general

このリンクにinstallations/newを付与して、インストールURLとします、
DIMBULA の場合は、以下になります。

https://github.com/apps/dimbula-real-mobile-ci-computing/installations/new

https://docs.github.com/ja/apps/maintaining-github-apps/installing-github-apps#allowing-people-to-install-your-public-app-on-their-repository

stateの付与

インストールのURLにstateを必要に応じて付与することができます。例えば、インストールするユーザ情報を示す文字列です。URLに露出する形で提供するため、見られて困るような情報であれば、有効期限付きの一時的な文字列でアクセストークン化するなど行っても良いと思います。

https://docs.github.com/ja/apps/maintaining-github-apps/installing-github-apps#preserving-an-application-state-during-installation

installation_idの取得

Github Appは、インストール時に呼び出されるSetup URLを設定することができます。

Github SetUp URL

Github Appは前述の通り、個人アカウントに依存せずアクセストークンを取得し、組織や個人のリソースにアクセスできます。そのアクセストークンを取得するためには、インストール時のクエリに付与されたinstallation_idが必要になります。installation_idがどのユーザのものかを識別したい場合は、stateにユーザを特定するような情報を付与することを検討できます。

Octokitの初期化

Github APIを活用する場合のほとんどは、Githubが提供するOtcokitを利用するでしょう。

https://octokit.github.io/rest.js

REST APIを使ってリソースにアクセスするために、Octokitのクライアントを初期化する方法は、いくつかありますが、Github Appの場合は以下が利用できます。この方法では個人のOAuth認証で得たアクセストークンでOctokitを初期化する必要がなく、個人に依存しない利用方法が可能になります。

import {defineSecret} from "firebase-functions/params"

const githubAppId = defineSecret("GITHUB_APP_ID")
const githubAppPrivateKey = defineSecret("GITHUB_APP_PRIVATE_KEY")

const githubAppInstallationId = "GithubのSetUp URLで渡されたinstallation_id"
const octokit = await new App({
  appId: githubAppId.value(),
  privateKey: githubAppPrivateKey.value(),
}).getInstallationOctokit(githubAppInstallationId)

const app = await octokit.rest.apps.getInstallation(
  {installation_id: githubAppInstallationId})
const login = app.data.account?.login

// loginはインストールした個人や組織のアカウントを示す文字列
// kunimasu or kunimasu-com etc
// ただし個人か組織かは判断できないよう

最後に

個人のアクセストークンを運用で使い回す手間がGithub Appにすることで回避できるメリットは大きいと考えています。Github Appを作ること自体は機会の多いことではないと思いますが、作る際はもちろん、Github Appを活用する際のヒントになればと思います。

Discussion