Boto3におけるセッション開始時のMFAを省略する

2022.10.13

データアナリティクス事業本部のueharaです。

今回はBoto3でセッション開始時にキャッシュを利用してMFAを省略する方法について紹介します。

例として、bs-ueharaというroleが既にあり、スイッチ元のIAMユーザのMFA認証が有効となっていることを想定します。

(参考)CLIでのスイッチロールについて

CLI利用時のスイッチロールについては下記の記事で紹介されています。

IAM初心者がAWS CLIでスイッチロールするまで

MFAを設定しているとBoto3では何が面倒か?

まず初めに、AWS CLIでバケットのリストを取得してみます。

実行コマンド

aws s3 ls --profile bs-uehara

1回目の実行(AWS CLI)

1回目の実行なので、MFAのコードを入力要求が表示され、正しいMFAコードの入力を行うと結果が表示されます。

2回目の実行(AWS CLI)

1回目の実行結果が確認できたら、もう1度同じコマンドを入力してみます。

今度はMFAコードの要求がされませんでした。

これは、AWS CLI側が認証情報のキャッシュを保持しているためで、一定期間MFAコードの入力を省略することができます。

では、今度はBoto3での実行を見てみましょう。コードは下記の通りです。

session_test.py

import boto3


session = boto3.Session(profile_name='bs-uehara')

s3_client = session.client('s3')
print(s3_client.list_buckets())

1回目の実行(Python Boto3)

AWS CLIと同じように、MFAコードの要求が表示されます。

2回目の実行(Python Boto3)

MFAコードを入力して1回目の実行が完了した後、先のコードをもう一度実行してみます。

すると、AWS CLIの挙動とは異なり、再度MFAコードの入力が要求されます。

これは何故か?

Boto3利用時は1つのセッション内のメモリにのみ認証情報がキャッシュされ、ディスクに保持されないためこのような事象が発生します。

本題

MFA認証を省略するため、明示的にキャッシュを利用するよう記載を行います。

具体的には、botocoreでキャッシュを設定したセッション情報を作成し、それをBoto3のセッションに渡してやるようにします。

session_test.py

import os

import boto3
import botocore.session
from botocore import credentials


cli_cache = os.path.join(os.path.expanduser('~'), '.aws/cli/cache')

botocore_session = botocore.session.Session(profile='bs-uehara')
botocore_session.get_component('credential_provider') \
    .get_provider('assume-role').cache = credentials.JSONFileCache(cli_cache)

session = boto3.session.Session(botocore_session=botocore_session)

s3_client = session.client('s3')
print(s3_client.list_buckets())

実行結果

AWS CLIの2回目の実行結果と同じように、MFAコードの入力が省略されます。

最後に

今回はBoto3でローカルのキャッシュを用いたセッションを作成し、MFAを省略する方法について記載しました。

MFAは設定したいが、Boto3利用時に毎回MFAコードを入れるのが手間だという方の一助になれば幸いです。