GSuite 管理下アカウントの接続アプリ情報を確認する方法

[急速に広まったGmail/Google Docsのフィッシング詐欺に対してGoogleが公式声明を発表  |  TechCrunch Japan](http://jp.techcrunch.com/2017/05/04/20170503heres-googles-official-statement-on-todays-fast-spreading-phishing-attack/)
こんな記事がありまして、不用意に Gmail へのアクセスを許可してしまうと大変なことになるというのが周知されればそれはそれで今後のためにはなるかなという感じですが、良くわかんないけど便利そうだからと許可しちゃうってのはありそうです。GSuite において Google Drive へのアクセスはドメイン（組織）内からのみに限定可能ですが Gmail ではそれができません。

自分自身のアカウントについては[アカウントに接続されているアプリ](https://myaccount.google.com/permissions)で確認できますが、あなたが GSuite の管理者で、誰かが不用意にアクセスを許可していないか調べなければならないとしたらどうすれば良いでしょうか。

GSuite 管理者は誰がどんなアプリ、サイトにアクセスを許可しているかを [Google Apps Admin SDK](https://developers.google.com/admin-sdk/) Directory API の [Tokens](https://developers.google.com/admin-sdk/directory/v1/reference/tokens) で確認することができます。

`list` で次のようなレスポンスが得られます。`get` では `clientId` を指定することで当該 `clientId` に限定した情報が得られますが、`list` より得られる情報が増えたりはしません。利用者に確認するまでもなく削除が必要な場合は `delete` で当該アクセス権を削除できます。

```json
{
    "etag": "\"eqO3c9wtJJ4wVWz2xe0E9HiU_D0/2MNtXFuDDgEQvKBqfbFtTDmReGI\"",
    "items": [
        {
            "anonymous": false,
            "clientId": "292824132082.apps.googleusercontent.com",
            "displayText": "Google APIs Explorer",
            "etag": "\"eqO3c9wtJJ4wVWz2xe0E9HiU_D0/ZWXyg2w4w1l-_X9W1wX_vSO76fs\"",
            "kind": "admin#directory#token",
            "nativeApp": false,
            "scopes": [
                "https://www.googleapis.com/auth/apps.licensing"
            ],
            "userKey": "123456789012345678901"
        },
        {
            "anonymous": false,
            "clientId": "123456123456-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com",
            "displayText": "Zendesk",
            "etag": "\"eqO3c9wtJJ4wVWz2xe0E9HiU_D0/QXKjHjHAD9x50uNksx_wmy4kVLQ\"",
            "kind": "admin#directory#token",
            "nativeApp": false,
            "scopes": [
                "https://www.googleapis.com/auth/userinfo.email",
                "https://www.googleapis.com/auth/plus.me"
            ],
            "userKey": "123456789012345678901"
        },
        {
            "anonymous": false,
            "clientId": "Google Chrome",
            "displayText": "Google Chrome",
            "etag": "\"eqO3c9wtJJ4wVWz2xe0E9HiU_D0/sIMeSUCOeG2Jl1L5wIOh2MTQpgQ\"",
            "kind": "admin#directory#token",
            "nativeApp": true,
            "scopes": [
                "https://www.google.com/accounts/OAuthLogin"
            ],
            "userKey": "123456789012345678901"
        },
        {
            "anonymous": false,
            "clientId": "123123123123-123456abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com",
            "displayText": "Grafana",
            "etag": "\"eqO3c9wtJJ4wVWz2xe0E9HiU_D0/K6LTcWi4y797iMujMH9jeHFXQ-U\"",
            "kind": "admin#directory#token",
            "nativeApp": false,
            "scopes": [
                "https://www.googleapis.com/auth/userinfo.profile",
                "https://www.googleapis.com/auth/userinfo.email"
            ],
            "userKey": "123456789012345678901"
        }
    ],
    "kind": "admin#directory#tokenList"
}
```

それぞれに、どの権限を許可しているのかは `scopes` に入っています。
[https://developers.google.com/identity/protocols/googlescopes#scriptv1](https://developers.google.com/identity/protocols/googlescopes#scriptv1) などにあります。

## scope の一例

| scope | |
|--------------------------|--------------------------------------|
| https://mail.google.com/ | Read, send, delete, and manage your email |
| https://www.googleapis.com/auth/userinfo.profile | View your basic profile info |
| https://www.googleapis.com/auth/userinfo.email | View your email address |
| https://www.googleapis.com/auth/plus.me | Know who you are on Google |
| https://www.googleapis.com/auth/drive | View and manage the files in your Google Drive |
| https://www.googleapis.com/auth/drive.readonly | View the files in your Google Drive |
| https://www.googleapis.com/auth/spreadsheets | View and manage your spreadsheets in Google Drive |
| https://www.googleapis.com/auth/spreadsheets.readonly | View your Google Spreadsheets |
| https://www.google.com/m8/feeds | Manage your contacts |
| https://www.google.com/calendar/feeds | Manage your calendars |

などなど沢山あります

https://mail.google.com/ とか https://www.googleapis.com/auth/drive なんて怖すぎてとてもじゃないけど許可したくないですよね？でも意外と簡単に許可しちゃうんですよ...

[OAuth 2.0 Playground](https://developers.google.com/oauthplayground/) を見ると Gmail には個別の権限もあるっぽい

* https://www.googleapis.com/auth/gmail.compose
* https://www.googleapis.com/auth/gmail.insert
* https://www.googleapis.com/auth/gmail.labels
* https://www.googleapis.com/auth/gmail.metadata
* https://www.googleapis.com/auth/gmail.modify
* https://www.googleapis.com/auth/gmail.readonly
* https://www.googleapis.com/auth/gmail.send

## 一括で調査する

[https://github.com/yteraoka/googleapps-directory-tools](https://github.com/yteraoka/googleapps-directory-tools) に GSuite のアカウントを操作するスクリプト群があります。

`tokens.py` で [Tokens](https://developers.google.com/admin-sdk/directory/v1/reference/tokens) API にアクセスできます。

```
$ ./tokens.py
usage: tokens.py [-h] [--auth_host_name AUTH_HOST_NAME]
                 [--noauth_local_webserver]
                 [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
                 [--logging_level {DEBUG,INFO,WARNING,ERROR,CRITICAL}]
                 {list,get,delete} ...
tokens.py: error: too few arguments

$ ./tokens.py list
usage: tokens.py list [-h] [--scopes SCOPES] [--whitelist WHITELIST] [--json]
                      [--jsonPretty]
                      userKey
tokens.py list: error: too few arguments
```

`user.py` でアカウント一覧が取得できるので

```
$ user.py list -d example.com \
    | awk '{print $1}' \
    | xargs -n 1 tokens.py list
```

で example.com の全アカウントの接続アプリ情報が取得できます。
が、ノイズが多くても困るので `--scopes` で重要な scope だけ指定すればそれが含まれるアプリだけが表示されます。

```
$ tokens.py list \
  --scopes https://mail.google.com/ \
  --scopes https://www.googleapis.com/auth/drive \
  user@example.com
```

これでも全員が OAuth でログインするようなアプリがあったりすると邪魔なのでホワイトリストファイルとして `clientId` リストのファイルを作成し `--whitelist` でファイルを指定すると表示から除外できます。

```
$ ./user.py list -d example.com \
  | awk '{print $1}' \
  | xargs -n 1 ./tokens.py list \
      --scopes https://mail.google.com/ \
      --scopes https://www.googleapis.com/auth/drive \
      --whitelist whitelist.txt
```

こんな感じで怪しげなアプリに許可してないかチェックできますね。