GitHub AppsとOAuth Appsの違いが分からなかった人のために、日本一わかりやすく説明してみた

[PrAha Inc.](https://www.praha-inc.com/)CEOで、時々エンジニアのモノマネしてます、[dowanna](https://twitter.com/dowanna6)です。個人的にGitHub AppsとOAuth Appsの違いが最初は分かりづらかったので、解説してみます。

# 結論
- GitHub Apps は「installation」を作成する事で、そのinstallationに追加されたリソースを操作できるようになる
- OAuth Apps は「誰かとして認証」する事で、そのユーザが持つ権限の範囲内で、リソースを操作できるようになる

## こんなイメージ

### GitHub Appsの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246648/48bb457d-fffc-5e17-d59d-8ac0e31359b2.png)

1. GitHubAppを作成して
2. そいつらの分身である[Installation]を作成して
3. UserもしくはOrganizationに紐付ける

以降はInstallationが、自分自身に紐付けられたUserもしくはOrganizationのリソース（Repositoryなど）を扱えるようになります。**ガンダムで言う所のハロ、SONYで言う所のAIBO**みたいな、**自分の言う事を聞いてサポートしてくれるペット**を会社で共同保有してるようなイメージです。これがGitHub Apps。

### OAuth Appsの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246648/1d8638c0-0e81-baa4-2e43-de49d8d6a620.png)

1. OAuth Appに、自分の分身として動く事を許可する
2. OAuth Appは、GitHub Userになりすまして行動する

以降OAuth Appは誰かになりすまして、その人として振る舞いながら、リソースを扱えるようになります。先ほどのAIBOやハロとは違い、ペットではありません。**NARUTOで言う所の影分身**。これがOAuth Appsのイメージだってばよ。


## つまり
GitHub Apps -> ハロ、AIBOを飼ってる
Oauth Apps -> 影分身を作り出してる


このイメージさえ持っていれば、以降の理解は早いと思います！


## そもそも、何の問題を解決するためにGitHubAppが生まれたのか
サービスが新たに誕生するときは、何らかの背景課題があるもの。その背景課題を理解することが、サービスを理解する近道。まずはGitHub Appsが存在しないと何が起きるのか説明しましょう。

## OAuth Appsの存在理由を知る
その前に、そもそもOAuth Apps(影分身)がなぜ存在するのか説明しましょう。

### クローラーを作る
ある日、あなたは上長にこんな事を頼まれます。

上長「commit数を日付順に並べてくれ」

（Insights見ろよ・・・）

と思いつつ、[上長の丸太のような足蹴りに股間を潰される](http://jojowords.info/part1.html)ことに恐れをなしたあなたは、仕方なくcommitを数える事になりました。

とはいえ、手動でcommitをページネーションし続けて、エクセルにハッシュと日付を転機していくのは正気の沙汰ではありません。

「この作業、機械が代わりにやってくれねーかなー」と考えたあなたは、クローラーを作ることにしました。

しかし対象レポジトリがPrivateなら、クローラーからアクセスする事は出来ません。そこであなたは閃きます。
「selenium使って、ログイン画面にメールアドレスとパスワードを入力して、hogeUserとしてログインしてからクローリングすれば大丈夫だ！」

つまりクローラーに貴方としてログインさせる事で、クローラーが貴方に成り済ますわけです。


#### これはセキュリティ上、よろしくない
でも、これだとメールアドレスとパスワードが漏洩する危険がありますよね。万が一漏洩した時にはパスワードを変更しなければいけません。もし流出後に、パスワードが悪意ある第三者によって変更されていたら、完全にアカウントを乗っ取られてしまいます。

そんな時に役立つのがOAuth Appsです。


### パスワードではなく、トークン
OAuth Appsではメールアドレスとパスワードの代わりに**トークン**を使います。**水戸黄門の印籠みたいなものだと思ってください**。その印籠さえ持っていればGitHubは「この印籠を持ってるって事は、こいつ水戸黄門じゃね・・・？」と認めてくれます。

そしてトークンは、いつでも無効化できます。なので万が一漏洩した時は「このトークンは漏洩しちゃったから使わないでね」と指示すれば、もう盗まれたトークンであなたに成りすます事は出来ません。

「その印籠、もう無効だから」みたいな。
「無効な印籠を見せてくるなんて、さてはお前、アンチだな？」みたいな。


### OAuth Appの何が問題なの？
印籠システム、バッチリじゃん！と思うかもしれませんが、いくつか問題があります。
- アクセス権限が広すぎる
- トークンが長生き
- 人的ミスを防ぎづらい


#### アクセス権限が広すぎる
誰かになりすましたOAuth AppがPrivateレポジトリにアクセスするためには「repo」権限が必要なのですが、この権限、**読み書きがセットです**。つまりクローラーに誤ってコードを全削除するスクリプトが紛れ込んでしまった場合、ガチでPrivateレポジトリの中身がすべて消えます。

なので一般的なエンジニアは、OAuth Appにrepo権限を求められると「いやっ！やめてっ！」と強烈な拒否を示します。

#### トークンが長生き
「トークンが漏洩したら、失効させればいいじゃない」とアントワネットみたいな事を先ほど言いましたが、ここにも実は問題があります。**漏洩した事に気づかなければいけないのです。**「ずっと昔にOAuth Appのトークンが漏洩してたけど、気づかずそのままになってたので、ずーっと不正利用されてた」なんてことがあり得るわけです。

#### 人的ミスを防ぎづらい
上記の問題から、貴方のOrganizationはOAuth Appの人的ミスを防ぐため、権限を限定したいと考えました。

**が・・・、ダメっ！OAuth Appっ、紐づく・・・User自身に！ゆえに・・・組織の意向・・・受け付けずっ！**

ユーザがOAuth Appにどんな権限を与えるか、Organization側が指定する手段はありません。影分身にどこまでの権限を渡すかは、ユーザーが決める事です。なのでユーザが誤ってrepo権限を影分身に渡してしまい、その影分身がOrganizationに対して致命的な破壊工作を行ってしまう事もあり得ます。

organization側の設定で「**すべてのthird partyアプリケーションから、当リソースへの[アクセスを禁ずる](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/enabling-oauth-app-access-restrictions-for-your-organization)！！**」みたいな事は出来ますが、それだと優良なthird partyアプリケーションまで使えなくなります。

No pain, no gain

リスクを飲んで恩恵を受けるか、一切使えなくするか。すごく極端な命題を迫られます。

## 問題点のおさらい
一言で言うと、「**影分身、やれること多すぎね？悪い影分身だったらどうするの？**」ってのがOAuth Appの問題です

## GitHub Appsは、それをどう解決するのか

### 人的ミスを防ぎづらい問題
GitHub Appsの場合、installationを組み込む必要があり、Organizationの場合は管理者しかinstallationを入れられません。
なので「間違って何でもできる影分身入れちゃいました〜テヘッ☆」みたいな人的ミスは、管理者が賢明な限りは防げます。管理者がテヘッたら、それはもう会社がテヘッです。

### トークンが長生き問題
GitHub Appsは[短期間で失効するトークン](https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/)と、新しいトークンを手に入れるためのトークン、つまり数種類のトークン組み合わせる事で安全性を高めています。

水戸黄門が役所に免許証を持っていくと、その日だけ使える新しい印籠が支給されるようなものですね。
「この印籠が目に入らぬか！」って次の日も同じ印籠を使うと賊に「**あれ、それ失効してね？**」って突っ込まれるイメージです。

### アクセス権限が広すぎる問題
めちゃくちゃ細かく[設定](https://developer.github.com/apps/managing-github-apps/editing-a-github-app-s-permissions/)できます。


# まとめ
この記事では「そもそもGitHub AppsとOAuth Appsは何が違うのか分からん」「何で似たものが2つ存在するのか分からん」と混乱した人のために、大まかな違いと、その背景を説明するに留めていますので、細かな話は公式ドキュメントに譲ります。

割と僕は最初のうち「こいつら何が違うねん」とさっぱり分からなかったので、この記事をキッカケにGitHub Appsの理解が少しでも深まると嬉しいです。もし何か間違っていたらビシバシご指摘ください！