credential_process でAssumeRoleする

はじめに

福岡オフィスのyoshihitohです。

Rust用の(非公式)AWS SDK Rusotoのチェンジログ を見ていると、 ~/.aws/configcredential_process をサポートしたぜ!と書かれていました。

初めて見る設定だったのでどういう動きをするか試してみました。

前提条件

  • aws-cli: 1.16.140 Python/3.7.3 Darwin/17.7.0 botocore/1.12.130
  • jq: 1.6

credential_process とは

AWS CLI Configuration Variables — AWS CLI 1.16.140 Command Reference

If you have a method of sourcing credentials that isn't built in to the AWS CLI, you can integrate it by using credential_process in the config file. The AWS CLI will call that command exactly as given and then read json data from stdout.

外部プロセスの標準出力から認証情報を取得する仕組みとのことです。直前の警告にあるように、 credential_process を使う場合はセキュリティ面の考慮が必要であることに留意してください。

認証情報は以下の形式のJSONでなければなりません。

{
  "Version": 1,
  "AccessKeyId": "",
  "SecretAccessKey": "",
  "SessionToken": "",
  "Expiration": ""
}

どっかで見たような形式だなぁと思ったら、STS AssumeRoleのレスポンスCredentials とほぼ同様の形式です。違いは "Version": 1 の部分だけっぽいです。

credential_process の挙動を確認するため、STS AssumeRoleで取得した認証情報を使って試してみます。

認証情報取得用のスクリプト

動作確認用に、STS AssumeRoleで一時的な認証情報を取得するスクリプトを書いてみます。上述の通り Credentials の内容を抽出することと、 "Version": 1 の指定を追加するため jq コマンドを使います。

#!/usr/bin/env bash

ROLE_ARN='YOUR_ROLE_ARN'

aws --output json \
    sts assume-role \
    --role-arn "$ROLE_ARN" \
    --role-session-name ar-cred-proc \
| jq ".Credentials + {Version: 1}"

jq コマンドの .Credentials 指定で一時的な認証情報を抽出します。これだけだとcredential_processの指定で必要な Version が含まれないので、 + {Version: 1} を指定してフィールドを追加します。

MFAが必須の場合は --serial-number--token-code オプションでMFAシリアル番号とワンタイムトークンを指定しましょう。

credential_processが期待する形式になるか試してみます。

$ chmod u+x /path/to/my-script.bash
$ ./path/to/my-script.bash
{
  "AccessKeyId": "XXXXXXXXXXXXXXXXXXXX",
  "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "SessionToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "Expiration": "2019-04-10T23:00:000",
  "Version": 1
}

試してみる

手軽に確認するため、S3バケットの一覧を表示してみます。 まず、AWSプロファイルを指定しない場合はアクセス権限でエラーになることを確認します。その後で上記スクリプトを実行する指定を追加し、S3バケットの一覧を表示できることを確認します。

credential_process未指定の場合

credential_processの指定無しでAWS CLIを実行します。

[test-credential-process]
# empty
$ aws --profile test-credential-process s3 ls
Unable to locate credentials. You can configure credentials by running "aws configure".

認証情報が見つからないというエラーになりました。

credential_processを指定する場合

~/.aws/config に設定を追加します。

[test-credential-process]
credential_process = /path/to/my-script.bash

上記で追加したプロファイルを指定してAWS CLIを実行します。

$ aws --profile test-credential-process s3 ls
2018-08-27 21:44:27 cf-templates-xxxxxxxxxxxx-ap-northeast-1
...

バケットの一覧が表示されました。認証情報の指定が効いていそうです!

おわりに

今回は credential_process とSTSのAssumeRoleで取得した一時的な認証情報を組み合わせてAWSのAPIを実行してみました。 便利そうなのでいい感じの使い方が無いか、引き続き試してみたいと思います!

参考