Boto3（AWS SDK for Python）の利用する認証情報

Boto3の利用する認証情報は「[Credentials — Boto 3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)」にまとめられており、8か所から規定の順序で認証情報が検索されます。

# 認証情報の検索順序

Boto3はパラメーターやプロファイルなど複数の方法で認証情報を取得しようとする。その方法と順序は「[Configuring Credentials - Credentials — Boto 3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#configuring-credentials)」にあって、該当部分の拙訳は以下の通り。

> boto3の資格情報検索メカニズムは、以下のリストに沿って検索し、資格情報を見つけたらそこで停止することです。Boto3が資格情報を検索する順序は:
> 
> 1. `boto.client()` メソッドにパラメーターで渡された資格情報
> 2. `Session` オブジェクトの生成時にパラメーターで渡された資格情報
> 3. 環境変数
> 4. 共有された認証情報ファイル（`~/.aws/credentials`）
> 5. AWS設定ファイル（`~/.aws/config`）
> 6. ロールの引き受けの提供
> 7. Boto2設定ファイル（`/etc/boto.cfg and ~/.boto`）
> 8. IAMロールを構成されたAmazon EC2インスタンス上ではそのインスタンスメタデータサービス

これらのうち、APIアクセスキーとAPIシークレットキー、または名前付きプロファイルを使用するものについて、以下で見ていきます。

## 1. `client()` メソッド、 `resource()` メソッドでの直接指定

`boto3.client()` メソッドまたは `boto3.session.Session().client()` メソッドに、以下をパラメータで指定します。

|キー|指定値|
|---|---|
|aws_access_key_id|APIアクセスキー|
|aws_secret_access_key|APIシークレットキー|
|aws_session_token|（多要素認証時）セッショントークン|

以下は対話型シェルでの実行例です。

~~~
>>> import boto3
>>> client = boto3.client('iam', aws_access_key_id='YOURACCESSKEY', aws_secret_access_key='YOURSECRETKEY')
>>> client.list_users()
~~~

`client()` ではなく `resource()` （`boto3.resource()` または `boto3.session.Session().resource()` ）メソッドを使う場合でも、上記の3パラメータを指定できます。

~~~
>>> import boto3
>>> resource = boto3.resource('iam', aws_access_key_id='YOURACCESSKEY', aws_secret_access_key='YOURSECRETKEY')
>>> list(resource.users.all())
~~~

## 2. `Session` オブジェクトの生成時にパラメーターで渡された資格情報

### 認証情報の指定

`boto3.session.Session()` でsessionオブジェクトを生成する際に、以下をパラメータで指定します。生成されたSessionオブジェクトから `client()` メソッドで生成されたクライアントや `resource()` メソッドで生成されたリソースはこの資格情報を使用します。

|キー|指定値|
|---|---|
|aws_access_key_id|APIアクセスキー|
|aws_secret_access_key|APIシークレットキー|
|aws_session_token|（多要素認証時）セッショントークン|

以下は対話型シェルでの実行例です。

~~~
>>> import boto3
>>> session = boto3.session.Session(aws_access_key_id='YOURACCESSKEY', aws_secret_access_key='YOURSECRETKEY')
>>> client = session.client('iam')
>>> client.list_users()
~~~

### プロファイルの指定

`boto3.session.Session()` でsessionオブジェクトを生成する際に、以下をパラメータで指定します。指定された[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html)に構成されている認証情報が使用されます。生成されたSessionオブジェクトから `client()` メソッドで生成されたクライアントや `resource()` メソッドで生成されたリソースはこの資格情報を使用します。

|キー|指定値|
|---|---|
|profile_name|プロファイル名|

以下は対話型シェルでの実行例です。

~~~
>>> import boto3
>>> session = boto3.session.Session(profile_name='YOURPROFILENAME')
>>> client = session.client('iam')
>>> client.list_users()
~~~

## 3. 環境変数

### 認証情報の指定

以下を環境変数で指定します。前項まででの明示的な認証情報の指定がない場合、これが使われます。

|環境変数名|指定値|
|---|---|
|AWS_ACCESS_KEY_ID|APIアクセスキー|
|AWS_SECRET_ACCESS_KEY|APIシークレットキー|
|AWS_SESSION_TOKEN|（多要素認証時）セッショントークン|

以下はbash環境で上記環境変数を設定後、Pythonの対話型シェルを呼び出しての実行例です。

~~~
$ export AWS_ACCESS_KEY_ID=YOURACCESSKEY
$ export AWS_SECRET_ACCESS_KEY=YOURSECRETKEY
$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> client = boto3.client('iam')
>>> client.list_users()
~~~

### プロファイルの指定

以下を環境変数で指定します。前項まででの明示的な認証情報の指定がない場合、この指定された[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html)に構成されている認証情報が使用されます。

|環境変数名|指定値|
|---|---|
|AWS_PROFILE|プロファイル名|

以下はbash環境で上記環境変数を設定後、Pythonの対話型シェルを呼び出しての実行例です。

~~~
$ export AWS_PROFILE=YOURPROFILENAME
$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto3
>>> client = boto3.client('iam')
>>> client.list_users()
~~~

## 4. 共有された認証情報ファイル（`~/.aws/credentials`）

ここまでの認証情報がない場合、認証情報ファイル（`~/.aws/credentials`）内に `default` プロファイルとして構成されている認証情報が使われます。これは通常、AWS CLIを最初に使うときに `aws configure` コマンドで設定されています。詳細は「[AWS CLI のかんたん設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration)」を参照してください。

## 5. AWS設定ファイル（`~/.aws/config`）

ここまでの認証情報がない場合、AWS設定ファイル（`~/.aws/config`）内に `default` プロファイルとして構成されている認証情報があれば、これが使われます。ただし通常は、AWS設定ファイル内で管理しているプロファイル情報はリージョン（`region`）とデフォルトの出力形式（`output`）で、認証情報は含まれていません。

## 7. Boto2設定ファイル（`/etc/boto.cfg and ~/.boto`）

ここまでの認証情報がない場合、Boto2設定ファイルが存在すればそこに格納された認証情報が確認されます。Boto2設定ファイルはデフォルトでは `/etc/boto.cfg` または `~/.boto` に設置されます。以下が内容例です。

~~~
# Example ~/.boto file
[Credentials]
aws_access_key_id = foo
aws_secret_access_key = bar
~~~

これは後方互換性のための動作で、Boto2設定ファイルはCredentialsセクション以外無視されます。

# 認証方法と指定方法と優先順位

Boto3で利用できる認証情報には、(a)APIアクセスキーとAPIシークレットキー、(b)デフォルトプロファイル、(c)名前付きプロファイル、(d)ロール（ここでは詳細は触れませんでした）による認証の4種類が可能ということになります。これとここまでの指定方法を対応付けると、次のようになります。

|認証方法|指定方法|
|---|---|
|(a)APIアクセスキーとAPIシークレットキー|1、2、3、4、5、7|
|(b)デフォルトプロファイル|4|
|(c)名前付きプロファイル|2、3|
|(d)ロール|6、8|

想定した認証方式が使われていないと思ったときには、より優先順位が高い指定方法で別の指定がされていないかを確認することも必要そうです。

例えば `AWS_PROFILE` 環境変数で名前付きプロファイルを指定していても、もし `boto3.session.Session()` で別のプロファイル名が指定されてしまえば、そちらが優先されてしまいます。意図的にやっている場合は気づくでしょうが、デフォルト値がどこかで入り込んでいたりすると分かりにくくなりそうです。

# 参考

boto3の認証について。

* [Credentials — Boto 3](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)

AWSの認証情報ファイルと設定ファイルについて。

* [設定ファイルと認証情報ファイルの設定 - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html)
* [名前付きプロファイル - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html)
* [AWS CLI のかんたん設定 - AWS CLI の設定 - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html#cli-quick-configuration)

boto3の各メソッドについて。

* [boto3.client()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/boto3.html#boto3.client)
* [boto3.reference()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/boto3.html#boto3.reference)
* [boto3.session.Session().client()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.client)
* [boto3.session.Session().resource()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session.resource)
* [boto3.session.Session()](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html#boto3.session.Session)

Boto2設定ファイルについて。

* [Boto Config — boto v2.49.0](http://boto.cloudhackers.com/en/latest/boto_config_tut.html#credentials)
* [Credentials — Boto 3 Docs 1.12.26 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html#boto2-config) - Boto2 Config