macOSのAWSクレデンシャル管理

以前に[HashiCorp VaultとdirenvでAWSのcredentialsを管理してみた](https://qiita.com/Ricordanza/items/ccba331dc9093cca64ad)という記事でCodeanywhere上でのクレデンシャル管理についてメモを残しましたが、今度はmacOS上での管理についてざっくり調べてます。
ディスクはFileVaultで暗号化していますがやっぱり平文がなんとなくいやなので今回はキーチェーン上でクレデンシャルを管理する前提でツールを比較してみました。
（キーチェーンのセキュリティ云々言い出すとキリがないのでそこは割り切ってます。）

## 環境
macOS Mojave (10.14.5)

## 今回ざっと目を通したツール
- envchain
- awscli-keyring
- aws-vault

これら以外にもキーチェーンで管理するためのツールはありましたがパッと見て特徴的に感じたものみピックアップして比較してます。

## 各種ツールのざっくり比較

|                   |envchain           |awscli-keyring               |aws-vault           |
|:------------------|:-------------------------------|:----------------------------|:-------------------|
|インストール方法      |brew |pip |brew cask |
|コマンド             |envchain |aws ※CLIのプラグイン |aws-vault, aws ※credential_processに対応 |
|キーチェーンのファイル |ログイン |ログイン |aws-vault |
|キーチェーンの名前    |envchain-* |awscli:key |aws-vault (\*), aws-vault session for \* |
|設定値の確認コマンド   |envchain *foo* printenv *bar* |aws keyring show *foo* |aws-vault exec *foo* -- env \| grep AWS |  

awscli-keyringはAWS CLIのプラグインなので独自のコマンドは存在しない。
aws-vaultは独自コマンド以外にもcredential_process用のjsonを出力する機能を有しているのでconfigに指定も可能。

## ツールの概要

### envchain
[README](https://github.com/sorah/envchain)にあるとおりキーチェーンから環境変数をセットする汎用的なツール。
AWSクレデンシャル用というわけではないけどツールの紹介で触れられているので試してみました。
このツールだけではないが、環境変数を使う場合のセキュリティと利便性についての[記事](https://diary.sorah.jp/2014/06/05/securing-environment-variables)が上がっているので参考になる。

#### インストール

```
$ brew install envchain
```

#### 利用方法
以下のコマンドでクレデンシャルを登録すると設定完了。

```
$ envchain --set foo AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY
foo.AWS_ACCESS_KEY_ID: ...
foo.AWS_SECRET_ACCESS_KEY: ...
```

利用はAWS CLIのコマンドの前に先に登録したクレデンシャルの名称を指定。

```
$ envchain foo aws s3 ls
``` 

こうすることプロセスの環境変数にクレデンシャルが設定される。
`--profile` には対応していない。
他にもAWS CLIの環境変数を登録しておけばそれらを展開することも可能。
AWS CLI用ではないので平文管理はちょっと嫌だなーという情報（例は思い浮かばない。。）をキーチェーンで管理したい場合なんかに使える汎用的なツール。

### awscli-keyring
[README](https://github.com/sj26/awscli-keyring)にもあるとおりAWS CLIのプラグインとして開発されたツール。
AWSのクレデンシャルをキーチェーンで管理する事を目的としたプラグイン。macOSのキーチェーン以外でも使えるようだが未検証。

#### インストール
ツールをインストール

```
$ pip install awscli-keyring
```

**pipでインストールしただけだとImportError: cannot import name 'ConfigFileWriter'って怒られます。Githubのコードは対応済みのようなのでPyPI経由でインストールする場合は自分でパッチを当てないといけない。**    

AWS CLIにプラグインを登録

```
$ aws configure set plugins.keyring awscli_keyring
```

~/.aws/configに以下を追加。

```
[plugins]
keyring = awscli_keyring
```

#### 利用方法
以下のコマンドでクレデンシャルを登録すると設定完了。

```
$ aws --profile foo keyring add
AWS Access Key ID [None]: ...
AWS Secret Acess Key [None]: ...
```

利用はAWS CLIの普通の使い方と同じ。

```
$ aws s3 ls --profile foo
```

CLIで利用する認証情報をキーチェーンで管理するためのプラグインなので利用時のコマンドに変更はない。

### aws-vault
[README](https://github.com/99designs/aws-vault)にもあるとおりこちらはenvchainのようなキーチェーンを環境変数に展開するつくりだけど、AWSに特化した作りになっている模様。
~/Library/Keychains/aws-vault.keychain-dbというキーチェーンファイルを独自に作成してそこで情報を管理している。
このため、デフォルトのキーチェーンとは別の期間でロックを掛けたりとか設定することができる。
最初に設定したクレデンシャルから一時的なキーを取得してそれを環境変数に展開するので `ps -E` とかで見えるクレデンシャルも一時的な認証情報なのが好印象。
AssumeRoleも設定ファイルで完結することができたり、AWS Management Consoleにログインするためのコマンドがあるなど多機能な印象。
一時的な認証情報を利用するので期限が過ぎたらどうなるんだろという疑問は残るがそこまでは調べてません。

#### インストール

```
$ brew cask install aws-vault
```

#### 利用方法1（環境変数利用）
以下のコマンドでクレデンシャルを登録すると設定完了。

```
$ aws-vault add foo
Enter Access Key Id: ...
Enter Secret Key: ...
```

利用時はenvchainと同じく環境変数を経由するが設定時に登録したクレデンシャルではなく一時的な資格情報を環境変数に展開している。

```
$ aws-vault exec foo -- aws s3 ls
```

一時的な資格情報ではなく登録したクレデンシャルをそのまま利用したい場合は `--no-session` パラメータを利用する。

```
$ aws-vault exec foo --no-session -- aws s3 ls
```

#### 利用方法2（プロファイル利用）
以下のコマンドでクレデンシャルを登録する。（ここは利用方法1と同じ）

```
$ aws-vault add bar
Enter Access Key Id: ...
Enter Secret Key: ...
```

~/.aws/configに以下を追加。

```
[profile bar]
credential_process=aws-vault exec -j bar
```

こちらでも `--no-session` パラメータを指定して登録したクレデンシャルをそのまま利用可能。

```
[profile bar]
credential_process=aws-vault exec -j bar --no-session
```

利用は普通のプロファイルと同じようにAWS CLIで指定するだけ。

```
$ aws s3 ls --profile bar
```

## まとめ
AWS CLI用のクレデンシャルをキーチェーンで管理するためのツールは他にも、awskeyring、aws-keyring、aws-keychainなどそれなりにありましたが、メンテナンス状況を見るとaws-vaultが活発な印象。

Docker上でクレデンシャルを使いたい場合にホストの.awsをマウントして利用するなどの方法がありますが、キーチェーンを使うとこれらの方法は利用できず、環境変数に展開して対応する必要があります。
aws-vaultを利用する場合の例になりますが[こちらの記事](https://ryanparman.com/posts/2019/running-aws-vault-with-local-docker-containers/)にあるように必要な環境変数をコンテナに引き渡してあげるなどひと手間必要になります。

credential_processの存在を初めて知って便利だなーと思ったけど、利用時はセキュリティに注意しろよ！という記載が[公式のドキュメント](https://docs.aws.amazon.com/cli/latest/topic/config-vars.html#sourcing-credentials-from-external-processes)にあるのでご利用は計画的に。

暗号化されたディスク上であっても平文でクレデンシャルを管理するのは嫌だなーという人は試してみると良いかもです。

## 追記
default プロファイル指定時に aws-vault に登録しているクレデンシャルを選択する方法を[AWS CLI v2とaws-vaultとpecoを使ってプロファイルを選択方式にする](https://qiita.com/Ricordanza/items/fb873407b57089300748) に書きました。