Mac を起動すると「アプリケーション"ksadmin"を使用するためのアクセス権がありません。」ダイアログ

macOS HighSierra で、セキュリティを強化した（アプリケーションの制限をかけた）ら、起動時に「アプリケーション使用するためのアクセス権がありません」エラーメッセージが出ました。

<img width="100%" alt="スクリーンショット 2018-10-26 21.31.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/33c81a1c-a299-e223-70fe-e179a85d38f5.png">

「許可」すればいいだけなのですが、"ksadmin" とは何のアプリか気になったので調べてみました。

- 動作／検証環境
    - macOS HighSierra（OSX 10.13.6）
    - Google Chrome 70.0.3538.77（Official Build） （64 ビット）

## TL;DR（概要）

> 「`ksadmin`」は、**Google Chrome の不具合情報の確認・報告などの管理コマンド・アプリ**です。
>
> Google のサービス（監視アプリ）が、起動時に不具合の最新チケット情報を確認しようとするも、`ksadmin` に許可がないためエラーが表示されます。

このエラーメッセージを非表示にしたい場合は、**`GoogleSoftwareUpdateAgent` も許可する**必要があります。（表示される確認メッセージで、関連するアプリを「常に許可...」でも可）

<img width="100%" alt="スクリーンショット 2018-10-28 0.25.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/563e8e63-cbdc-c737-75ce-16f8f5e5cf8a.png">

### 関連アプリ

`ksadmin` 以外にも、以下のアプリで「アプリケーション "xxx" を使用するためのアクセス権がありません」エラーが発生する場合があります。

1. `ksadmin`
2. `ksfetch`
3. `crashpad_handler`
4. `GoogleSoftwareUpdateDaemon` 

ディレクトリで許可出来る場合は下記ディレクトリ以下を許可します。

```
/Library/Google/GoogleSoftwareUpdate
```

## TS;DR（詳細）

`ksadmin` は、アプリのクラッシュや予期せぬエラーなどが発生した場合、Google に送る[チケット](https://ja.wikipedia.org/wiki/%E3%83%81%E3%82%B1%E3%83%83%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)（障害報告）の発行、もしくは発行済みの確認を行うコマンドで、[デーモン](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))や `crashpad_handler` コマンドなどが呼び出して Google に通知します。（両者のコマンドについては下記を参照）

しかし、この `ksadmin` コマンドは `GoogleSoftwareUpdate` [バンドル](https://en.wikipedia.org/wiki/Bundle_(macOS)#macOS_loadable_bundles)（アプリ）に内包されています。

### 該当アプリの設置先ディレクトリ

`ksadmin`, `ksfetch`, `crashpad_handler`, `GoogleSoftwareUpdateDaemon` などは下記ディレクトリに設置されています。（`GoogleSoftwareUpdate.bundle`の中）

```text:上記アプリのディレクトリ・パス
/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/
```

```shell-session
$ cd /Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle
$ cd /Contents/MacOS/
$ ls -la
total 1544
drwxr-xr-x  6 root  wheel     192  6  7 06:43 .
drwxr-xr-x  7 root  wheel     224  6  7 06:43 ..
-rwxr-xr-x  1 root  wheel  235088  6  7 06:43 GoogleSoftwareUpdateDaemon
-rwxr-xr-x  1 root  wheel  353680  6  7 06:43 crashpad_handler
-rwxr-xr-x  1 root  wheel  130672  6  7 06:43 ksadmin
-rwxr-xr-x  1 root  wheel   63936  6  7 06:43 ksfetch
```

つまり、[ペアレンタル・コントロール](https://ja.wikipedia.org/wiki/%E3%83%9A%E3%82%A2%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB)やセキュリティ・アプリなどで、起動できるアプリに制限をかけている場合で、Google Chrome のみを許可した場合に、`GoogleSoftwareUpdate` も許可しておかないと、`ksadmin` などの必要な関連する機能が起動／実行できない旨、エラーメッセージとして表示されます。

これは OS 起動時に、Google Chrome の既存の障害情報（チケット情報）の確認が行われるため、`ksadmin` が呼び出されるからです。

### アプリの役割

Google Chrome は、障害／クラッシュ／不具合などの報告に、[Chromium の Crashpad](https://chromium.googlesource.com/crashpad/crashpad/+/master/README.md) システムを利用しています。この Crashpad システムの通知サーバが [`crashpad_handler`](https://chromium.googlesource.com/crashpad/crashpad/+/master/handler/crashpad_handler.md) です。

<img width="100%" alt="スクリーンショット 2018-11-01 16.20.19_1200x.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/b3a81ed0-cc76-42f4-0581-0ffa793b8ae8.png">

`crashpad_handler` は、受け取った諸障害報告から Google に報告すべきバグであると判断した場合「[チケット](https://ja.wikipedia.org/wiki/%E3%83%81%E3%82%B1%E3%83%83%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)」と呼ばれる、作業タスクのようなものを発行し、Google のサーバーに送信します。

そして、`ksadmin` はそのチケットの発行および確認用のコマンドです。

<img width="100%" alt="スクリーンショット 2018-10-26 21.31.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/33c81a1c-a299-e223-70fe-e179a85d38f5.png">

`crashpad_handler` `ksadmin` どちらも、コマンドからの呼び出しが可能で、パスが通っていないので絶対パスで直打ち＋ヘルプ（`-help`オプション）でオプションや引数を[確認できます](#ksadmin-コマンドの詳細)。

また、バンドルされているアプリ名の「`Google Software Update`」からわかる通り、**`ksadmin` はソフトウェア・アップデート関連の一部**ということがわかります。

問題は、Google Chrome 自体は、自身の「Google Chrome について」メニューを開かないと最新バージョンの確認とアップグレード（バージョンアップ）を実行しません。

つまり、逆に言うと、**バージョンの確認をしない限り `Google Software Update` は呼び出されない**のです。

それなのに「OS 起動時にエラーがでるのは何故か」とデーモンが囁いたので気になりました。

### 呼び出されるタイミング

OS の起動時に表示されるということは、スタートアップ、サービスやデーモン類で呼び出されているということです。

しかし、スタートアップには追加されていなかったので、macOS のサービス登録を確認すると、いました。アプリをインストールした際にサービスに登録されてたようです。

```shell-session:launchctl
$ launchctl list | grep -e google -e Google
730	0	com.google.Chrome.41272
-	0	com.google.keystone.system.agent
```

```shell-session
$ ls -ld /Library/Launch*
drwxr-xr-x   9 root  wheel  288 10 25 19:06 /Library/LaunchAgents
drwxr-xr-x  14 root  wheel  448 11  1 08:41 /Library/LaunchDaemons
$
$ ls -la /Library/Launch* | grep -e google -e Google
-rw-r--r--@  1 root   wheel   792  7 18 07:46 com.google.keystone.agent.plist
-rw-r--r--@  1 root  wheel   818  7 18 07:46 com.google.keystone.daemon.plist
```

### `ksadmin` コマンドの詳細

<details><summary>`ksadmin --help`</summary><div>

```shell-session
$ cd /Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/
$ ./ksadmin --help
Usage: ksadmin [options]
  --delete,-d         Delete a ticket as specified by option --productid
  --list,-l           List the available updates, but don't install any
  --print-brand,-D    Get the brand code for a particular product.  Requires -P
  --print-tag,-G      Get the tag for a particular product.  Requires -P.
  --print-tickets,-p  Print all tickets and exit.  Can be abbreviated --print
  --print-version,-o  Evaluate the version version path, and version tag, and print the effective version.  Requires -P
  --register,-r       Register a new ticket as specified by options.
                      Register requires 4 ticket options: -P, -v, -u, and an --xcsomething
  --brand-key,-b      Set the brand code path key.  Requires -P and -B
  --brand-path,-B     Set the brand code path.  Requires -P and -b.  Specify empty string to remove
  --creation-date,-c  Set the creation date of the ticket
                      Format should be like '1/13/1961 1:13 PM'
  --tag,-g TAG        Set the ticket's tag.  Specify empty string to remove existing tag
  --tag-path,-H       Set the tag path.  Requires -P and -K.  Specify empty string to remove
  --tag-key,-K        Set the tag path key.  Requires -P and -H
  --version,-v VERS   You can also specify -P id and -v VERS to update an existing ticket's version
  --version-path,-a   Set the version path.  Requires -P and -e.  Specify empty string to remove
  --version-key,-e    Set the version path key.  Requires -P and -a
  --productid,-P id   ProductID; can be a GUID or a BundleID
  --store,-s FILE     Use FILE instead of the default ticket store.
                      Default means the system-wide if running as root, or
                      a per-user one if running as non-root
                      (either a per-user or system-wide one)
  --system-store,-S   Use the system-wide ticket store
  --user-store,-U     Use a per-user ticket store
  --user-initiated,-F This operation is initiated by a user; sets the ondemand tag for update checks
  --xcpath,-x PATH    Specify an existence checker that checks for the existence
                      of the given path
  --xclsbundle,-X BID Specify an existence checker that asks LaunchServices whether an
                      application exists with the given Bundle ID
  --xcquery, -q query Specify an existence checker that checks whether the given Spotlight
                      query returns any results
  --url,-u URL        You can also specify -P id and -u URL to update an existing ticket's url
  --cohortHint, -C hint Hint to the update server to move the application to the specified cohort
  --verbose,-V        Print activities verbosely
  --help,-h           Print this message
```

</div></summary>

### `crashpad_handler` コマンドの詳細

<details><summary>`$ crashpad_handler --help`</summary><div>

```shell-session
$ cd /Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/MacOS/
$ ./crashpad_handler --help
Usage: crashpad_handler [OPTION]...
Crashpad's exception handler server.

      --annotation=KEY=VALUE  set a process annotation in each crash report
      --database=PATH         store the crash report database at PATH
      --handshake-fd=FD       establish communication with the client over FD
      --mach-service=SERVICE  register SERVICE with the bootstrap server
      --no-rate-limit         don't rate limit crash uploads
      --reset-own-crash-exception-port-to-system-default
                              reset the server's exception handler to default
      --url=URL               send crash reports to this Breakpad server URL,
                              only if uploads are enabled for the database
      --help                  display this help and exit
      --version               output version information and exit

Report crashpad_handler bugs to
https://crashpad.chromium.org/bug/new
Crashpad home page: <https://crashpad.chromium.org/>
```

</div></details>

## 所感

### macOS をインターネットカフェの PC ように再起動で初期化させたかった

シェアハウスに共同で触れるマシンとして、永らく寝ていた iMac をクリーン・インストールしてシェアしようと思いました。

その際、[macOS をインターネットカフェの PC ように再起動でユーザー作業を「なかったこと」にさせる](https://blog.keinos.com/20181027_4273)ために、ゲスト・アカウントでペアレンタルコントロールを有効にしました。

<img width="100%" alt="スクリーンショット 2018-10-26 18.03.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/b2cd4bdd-f651-3a9e-221c-fb1c53a22788.png">

利用できるアプリも制限され、Finder 含め**非常に良い感じにシンプルになりました**。問題は起動時にアクセス権のメッセージが出るようになったことです。

<img width="100%" alt="スクリーンショット 2018-11-01 16.19.45_1200x.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/3cb0f92a-c508-9fc8-e57a-38376487365d.png">

まぁ、これでメッセージの内容はわかったので、安心して「常に許可...」することにしました。