42
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub API v3 の Scopes と Scope 一覧

Last updated at Posted at 2018-03-20

この記事は、GitHub API v3 を利用する際のスコープの一覧(Scopes)です。

TL; DR (今北産業)

  1. GitHub API で利用できるスコープの和訳一覧を載せてます。
  2. GitHub API における「スコープ」とはアクセス権のようなものです。
    (詳しくは TL; DR 参照)
  3. 複数スコープを指定したい場合は、スペース区切り(%201)で指定します。
    • 例:?scope=user%20public_repo

GitHub API で利用可能な「scope

基本的に GitHub の「scope」は Allowed List 方式(ホワイト・リスト方式)です。

つまり「基本的に全てをブロック」しておき「許可されたものだけ通す」タイプです。GitHub の場合、scope の指定がない場合は「該当するユーザーの公開情報のみ読み取り可能」な設定になっています。

そのため公開情報の閲覧以上の権限が必要な場合は、あらかじめ scope の範囲をリクエスト URL に添えて、対象ユーザーから許可を得る必要があります。(詳しくは TS; DR 参照)

以下は(2018/03/20 時点の)GitHub の Scopes 仕様ページから一部を抜粋して翻訳・加筆したものです。

スコープ名 スコープ対象 権限 備考
(指定なし) 公開ユーザープロファイル、公開リポジトリ情報、公開 gist 読み取りを許可 (指定なし、デフォルト)
repo 公開/非公開/Organization リポジトリ 読み取り/書き込みを許可 repo
コード/コミットステータス/招待/共同編集者、チームメンバーの追加/デプロイのステータス
repo:status 公開/非公開リポジトリ、コミットステータス 読み取り/書き込を許可 repo:status
このスコープは、コードへのアクセスを許可しないで、他のユーザーまたはサービスに非公開リポジトリのコミット状況へのアクセスを許可する場合のみ必要です。
repo_deployment 公開/非公開リポジトリ、デプロイ・ステータス 読み取りを許可 repo_deployment
このスコープは、コードへのアクセスを許可しないで、他のユーザーまたはサービスにデプロイ・ステータスへのアクセスを許可する場合のみ必要です。
public_repo 公開リポジトリおよび Organization 読み取り/書き込みを許可 public_repo
公開リポジトリにスターを付ける場合にも必要です。
(コード、コミットステータス、共同作業者、およびデプロイ・ステータス)
repo:invite リポジトリでコラボレーションするための招待状 招待状の受け入れ/拒否の機能を許可 repo:invite
このスコープは、コードへのアクセスを許可しないで、招待へのアクセスを他のユーザーまたはサービスに許可する場合のみ必要です。
admin:org Organization、チーム、メンバーシップ 完全な管理を許可 admin:org
write:org Organization のメンバーシップ 公開/非公開を許可 write:org
read:org Organization やチームのメンバーシップ 読み取りを許可 read:org
admin:public_key 公開鍵 完全な管理を許可 admin:public_key
write:public_key 公開鍵 作成、一覧表示、および詳細表示を許可 write:public_key
read:public_key 公開鍵 一覧と詳細の表示を許可 read:public_key
(作成は含まない)
admin:repo_hook 公開/非公開リポジトリのフック 読み取り/書き込み/ping/削除を許可 admin:repo_hook
write:repo_hook 公開/非公開リポジトリのフック 読み取り/書き込み/ping を許可 write:repo_hook
(削除以外を許可)
read:repo_hook 公開/非公開レポジトリのフック 読み取り/ping を許可 read:repo_hook
(書き込みと削除以外を許可)
admin:org_hook Organization のフック 読み取り/書き込み/ping/削除を許可 admin:org_hook
注: OAuth トークンは、OAuth アプリによって作成された Organization フックでのみ、これらのアクションを実行できます。個人のアクセストークンは、ユーザーが作成した組織のフックでのみ、これらの操作を実行できます。
gist Gist 書き込みを許可 gist
notifications ユーザー通知 読み取りを許可 notifications
repoスコープもこれと同じアクセス権を提供します。
user ユーザーのプロファイル情報 読み取り/書き込みを許可 user
user:emailuser:followのスコープにも同じアクセス権が含まれます。
read:user ユーザーのプロファイル情報 読み取りを許可 read:user
user:email ユーザーの電子メールアドレス 読み取りを許可 user:email
user:follow 他のユーザー フォロー/アンフォローを許可 user:follow
delete_repo 管理可能なリポジトリ 削除を許可 delete_repo
write:discussion チームディスカッション 読み取り/書き込みを許可 write:discussion
read:discussion チームディスカッション 読み取りを許可 read:discussion
admin:gpg_key GPGキー 完全な管理を許可 admin:gpg_key
write:gpg_key GPGキー 作成/一覧表示/詳細表示を許可 write:gpg_key
read:gpg_key GPGキー 一覧/詳細表示を許可 read:gpg_key

TS; DR (スコープを完全に理解した気になるコマケーこと)

実際に触れる GitHub API のスコープを利用したデモも後半で出てきますが、「ふいんき」で利用してセキュリティで失敗しないためにも、安心して使えるように最低限の基礎知識を先に紹介します。

スコープとは

API におけるスコープとはアクセス権のようなもの

英語の scope(スコープ)には「対象を絞る」「指定された範囲」「それに注力」「それを注視」と言った意味合いがあります。

例えば、プログラムなどでは「スコープ」は「変数のスコープ」といった使われ方をします。関数内で宣言された変数は、関数の外からアクセスできないといった「範囲を示す」使われ方です。

GitHub API における「スコープ」(Scope)とは「API で利用できる範囲を定めるために指定する項目」です。

顕微鏡の「スコープ」よりは、ゴルゴ(13)氏や、ボトムズのスコープドッグがターゲットに狙いを定める「スコープ」の方の意味合いに近く、スコープ内にあるものを狙います。スコープ外のものは眼中にありません。

つまり、実質的には API 版のアクセス権のようなイメージが近いかと思います。

アクセス・トークンとは

さて、GitHub に限らず API へのアクセスで重要なのがアクセス・トークンです。

GitHub OAuth App や GitHub App といった、GitHub の API を使った自作アプリの場合、まずはユーザーに承認してもらい、次にアプリは GitHub からアクセス・トークンを取得することになります。

もちろんユーザーが手動で発行したアクセス・トークン(プライベート・アクセストークンもしくはパーソナル・アクセストークン)をもらう方法でも可能です。

どの方法にしろアクセス・トークンを取得できたら、このアクセス・トークンを使い、ユーザーに替わってリポジトリやアカウントの操作をアプリから GitHub API 経由で行えます

トークン(token)とは

特定の世界、業界、コミュニティでしか通用しない「何か」によって価値が示された発行物をトークンと言います。

その「何か」は、物理的なもの・紙に書かれたもの・データなど、形態は関係ありませんが「プロトコルが同じ場合に有効なもの」です。

ここでいうプロトコルとは「事前の合意」です。

例えば、物理的なものではモノポリーやトランプなどのゲームで使われるチップだったり、イベント内でしか使えない入場コインや、パーティの食券などです。

モノポリーで使われるコインをパチスロに持って行っても使えないように、共通の価値観を持った間でしか価値がありません。吉野家のチケットを松屋に持って行っても使えないのも同様です。

そのため「コミュニティ内」や「価値観が同じ者同士」で、合意があれば特定のトークンを通貨の代わりとしても使うことは可能です。しかし、汎用的に物々交換の代わりには使われないためトークン自体は通貨のことではありません

「発行したものを、発行側が失効したり、無効にできる」という点もトークンの 1 つの特徴です。

例えば、ポイント・カードの「ポイント」と「トークン」との違いですが、「なんとかポイント」の場合は、ポイント自体は無効にはできず「アカウントのポイント数の増減をしているだけ」です。逆に「シリアル番号 ●● 番のチケットは無効」といったことができるのがトークンです。

【学習ポイント】
「トークン」と言われたら「他では使えない、ここだけの発行物」と考えてください。

コンピューターにおけるトークンは、基本的に数値や文字列などの数桁〜数十桁の小さなデータ(数値)です。連番のこともあれば、ランダムな数値の場合もありますが、桁数が多いと扱い辛いことから HEX 文字列(16進数の数値の文字列)が多く使われます。

例えば、機械学習などでは文書をブツ切りにしたデータ(単語や文節など)やパターンに付けた ID のようなものをトークンと呼んだりします。ID と呼ばずにトークンと呼ぶのは、その処理限りの番号で、次の処理や他の学習モデルではその番号は意味を持たないからです。

連番の場合だとセキュリティ的に問題がある場合、つまり番号が予測されると処理が乗っ取られるようなケースでは、予測不可能で、かつ扱いやすいものという観点からハッシュ値が多く使われます。

そして「アクセス・トークン」は、いわばアクセスに必要な通行証や入場チケットのようなものです。データにアクセスするのに必要なものであるため「アクセス・トークン」と呼ばれます。

ただの数値でしかありませんが、ユーザと API 間で意味(価値)のあるものとして「トークン」と呼びます。GitHub API のアクセス・トークンでは Qiita API のアクセス・トークンとして使えないのもトークンの特徴です。

パスワードと似ており、用途も守秘性の重要度もほぼ同じです。違いは、一般的に「アクセス・トークンはアクセスを監視する側が発行する」のと、「自分で決められない」「長ったらしくて覚えられない」くらいの違いです。銀行のワンタイム・パスワードを、海外ではトークンと呼ぶのもそのためです。

「GitHub アカウントでログイン」は応用技

「GitHub ログイン」、つまり「GitHub のアカウントでログインできる仕組み」ですが、実は GitHub はダイレクトなログイン機能を提供しているわけではありません

GitHub ログインを理解する前に、アクセストークンの取得方法について知る必要があります。具体的なサンプルは後述しますので、まずはザッと流れを見ましょう。

  1. あなたのアプリは、ユーザーを GitHub の認証ページにリンクで飛ばします。
    この時、事前に GitHub に登録して発行した、あなたのアプリ ID(クライアント ID)もリンクの URL に含めておきます。
  2. ユーザーは GitHub にログインし、あなたのアプリを承認します。
  3. 承認されると GitHub は指定された URL に承認コード付きで飛ばし返します。
  4. あなたのアプリは、3の URL から承認コードを読み取り、GitHub にリクエストするとアクセストークンが取得できます。

上記の流れを OAuth といいます。

そして、上記のステップ 4 で「あなたのアプリがアクセス・トークンを取得できた」ということは、その前の1〜3の段階で「ユーザーは GitHub にログインできた」かつ「ユーザーはあなたのアプリを承認した」ということです。

このプロセスを経て、アクセス・トークンが取得できたらログインしたとみなす、「応用技」的な仕組みを OAuth ログインと言います。GitHub ログインは、この OAuth ログイン・タイプのログインを使ったものです。

逆に言うと「GitHub ログインを実装する」と言うことは「アクセス・トークンも取得できる」ということでもあります。本来はそれが目的の仕組みなんですが。

家の鍵を預けるようなもの

ここまでで、あなたのアプリはユーザーから許可(承認)をもらい、受け取ったコードを使って、GitHub にリクエストするとアクセストークンが発行される流れがザクっと理解できたと思います。

「GitHub アカウントを持つユーザーのみログインさせたい」と思うも、アクセス・トークンを取得できるということは、「ユーザーが GitHub で出来ることをアプリからでも出来てしまう」ということでもあります。

自分のサイトやサービスの「ログインの外部認証システム」として GitHub を利用したいだけ・・なのに、ユーザーの変わりに GitHub の操作もできてしまうのです。

「アクセストークンの発行」は「ユーザーが利用しているサービスへの鍵を預る」という事と同意です。「パスワードと違うし」と舐めてかかると痛い目を見ます。

つまり、あなたのアプリが「どこまで操作させてもらえるか」を提示して、ユーザーから許可をもらうことが重要となります。

この、アクセス・トークンに紐づいた、操作できる範囲が「スコープ」になります。

いずれの利用法にしても、提示したスコープの範囲にユーザーが同意し許可を得られるとアクセストークンの発行依頼が可能になり、アクセストークンが発行されると、スコープ内の範囲でユーザーの代理で GitHub の操作がアプリから可能になります。

スコープの指定の仕方

さて、具体的なスコープの指定はリンク先の URL に含めます。

Web サイトやアプリなどで見る「GitHub でログイン」などのアレです。実際に触れるデモは後述しますが、以下は、その URL の例です。

「GitHubでログイン」リンクのリンク先URLの例
https://github.com/login/oauth/authorize?client_id=$OAUTH2_CLIENT_ID&scope=user%20public_repo

上記 URL を分解すると以下のようになります。

  • エンドポイント: https://github.com/login/oauth/authorize
  • クエリ①: client_id=$OAUTH2_CLIENT_ID
  • クエリ②: scope=user public_repo

「クエリ①」の $OAUTH2_CLIENT_ID の値ですが、あらかじめ GitHub 側で作成/登録した OAuth アプリもしくは GitHub アプリの設定にある「クライアント ID」と置き換えます。

🐒   ここで言う「クライアント」とは、あなたが作ったアプリのことで、アプリのユーザーのことではありません。「GitHub クライアント・アプリ」としてのアプリ ID と考えればいいと思います。

次に「クエリ②」ですが、アプリが求めるアクセス権の指定です。値が userpublic_repo であることに注目します。

つまり、スコープに「user」と「public_repo」の読み書き許可を求めています。具体的にはスペース区切りで羅列したものを URL エンコード1したもの(user%20public_repo)になります(その他のスコープの権限は上記一覧をご覧ください)。

この URL のリンク先(GitHub のサイト上)で、ユーザーは API のアクセス範囲(スコープ)を確認し、許可をします。

ユーザーの許可が得られると、GitHub のエンドポイントは、アプリ登録時にあらかじめ指定してあるリダイレクト先(コールバック先)に転送します。すでに認証済みの場合は、許可画面は表示されずストレートにリダイレクト先に転送されます。

いずれの場合も、認証(許可)済みの場合はリダイレクト時の URL クエリに code に暫定的な値付きでリダイレクトされます。

登録したリダイレクトURLが「https://mydomain.com/return/?staus=return」の場合
https://mydomain.com/return/?staus=return&code=xxxxxxxxxxxxxxxxxxxxxx

あとは(リダイレクト先の)アプリ側が、この code の値を別途 GitHub に POST するとアクセストークンが取得できます。

デモ

ここまでの一連の動きを実際に触れるように、ダミーの GitHub OAuth アプリを登録してみました。

下記リンクをクリックすると GitHub の認証画面に飛びます。その時の許可を求めている内容を確認してください。

いずれのリンクも、「Authorize KEINOS」ボタンを押すと、この Qiita 記事のページに戻ってくると思います。

スクリーンショット 2020-06-08 23.56.36.png

この記事に戻ってきたら、記事の URL を確認し、クエリに code=xxxxxxxxxxxxxxxxxxxxxx が付いているのを確認してみてください。

本来は、この code の値を使って GitHub にリクエストしてアクセス・トークンを取得します。

しかしながら、登録したアプリの URL(リダイレクト先)をこの Qiita 記事にしているため、当然ながら何もおきません。あしからず。

後日「なんじゃこれ?」とならないように、確認後はアプリ登録を解除してください。解除は、下記リンク先の設定画面で「DummyAppToSeeOAuthWork」を削除(お猿のアイコンを Revoke)します。

  • Authorized OAuth Apps: https://github.com/settings/applications @ GitHub
    • GitHub の [Settings]-[Application]-[Authorized OAuth Appsタブ] からも削除できます。身に覚えのないアプリ(サービス)がないか定期チェックをオススメします。

GitHub ログインやアクセストークン取得の具体的な方法については、この記事のスコープに関する範囲外なので割愛します。
詳しくは公式の「コールバックの設定」をご覧ください。個人的に、日本語のページより英語のページの方がわかりやすかったです。簡単に説明すると、取得した確認コード(code)、クライアントID、クライアント・シークレットを https://github.com/login/oauth/access_token のエンドポイントに POST します。

OAuth App 登録までの参考画像

  • Callbak URL(ユーザーが承認した後に転送・リダイレクトされる自分の Web アプリの URL 先)

    • https://qiita.com/KEINOS/items/216d138b0fdf994b9582 (この Qiita 記事)
  • GitHub OAuth App 登録画面
    GitHub OAuth App 登録画面

  • GitHub OAuth App Client ID 確認画面
    GitHub OAuth App Client ID 確認画面

OpenID とは

OpenID もしくは OpenID Connect とは、これまでの OAuth ログインと同じなのですが、"openid" という専用のスコープを用意したものです。

先にも述べましたが、アプリから見て「アクセストークンを取得する」というのは、ユーザーの家の鍵を預かるのと同じようなものです。ログインに限定した場合は「家の鍵と、名刺の入った棚の鍵」を預かったようなものです。

「相手の家に入れて(アクセストークンが使えて)、棚も開けられたので、そこにあった名刺(スコープが返したユーザー名やメアド)は鍵の持ち主のものである」ということをアプリ側が行っていることにお気づきでしょうか。

つまり、開けられる鍵(スコープ)を 1 つ間違えるとすべてコントロールできてしまうため、アプリ側もユーザ側も気を付けないといけないことが多く、怖い側面を持っています。

そこで、これまでの OAuth 仕組みから「なんちゃってログイン」の部分のみに限定し、その仕様に準拠していれば、どのサービスであっても同じプログラムでログインさせることができるようにしたものが OpenID もしくは OpenID Connect です。

具体的には、スコープに "openid" を用意し、API から得られる情報を明確に限定させた(制定した)ものです。

残念ながら GitHub API では openid のスコープは用意されていません。

TIPS

ちなみに code の値を使って取得したアクセス・トークンで API を叩いても動かない場合、スコープの範囲外の API 内容をリクエストした可能性があります。しかし、まずは返されたヘッダ(レスポンス・ヘッダ)情報を確認してみてください。

API を叩くには「curl https://api.github.com/hogehoge_api/?access_token=XXXXXXXGET すればおk」と案内するだけの記事が多いのですが、実はこれだけでは取得できません。

そこで、curl--head-I オプションを付けてレスポンス・ヘッダをみると、以下のような「ブラウザの User-Agent が抜けている」といったメッセージが返されていたりします。

Request forbidden by administrative rules. Please make sure your request has a User-Agent header (http://developer.github.com/v3/#user-agent-required). Check https://developer.github.com for other possible causes.

所感(そのスコープ、狙いは定まってますか)

とあるサイトで「GitHubアカウントでログインできるよ!」というのでログインしようとしたら、なんか「リポジトリの書き込み権限」とか聞かれました。「不審なモバイルアプリじゃないんだから、最低限の権限にしなさいよ」と、ログインするのをやめました。

「そもそも、アクセス権限の指定ってできないからなのかな?」と調べると「スコープ」で行えることがわかりました。しかし、GitHub API の使い方に関する Qiita 記事は多いのですが、まとまった GitHub のスコープ仕様の情報がなかなかなく、「他にスコープで設定できる項目はないの?」と思って調べようとしても、すぐにヒットしなかったので取りまとめて記事にしてみました。

  1. 【URLエンコード/パーセントエンコードとは】「パーセントエンコーディング」@ Wikipedia 2

42
33
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
33

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?