AWS OrganizationsのAWS IAM Identity Center(旧AWS Single Sign-On;AWS SSO)を利用すると、Organizations配下のAWSアカウントにSSOできます。
本記事では、同機能をAWS CLIから利用する方法を紹介します。
AWS IAM Identity Centerの詳細は次のブログを参照ください。
なお、本記事ではAWS Identity Center directoryでユーザー管理しているものとします。
ポイント
- IAM Identity CenterにはAWS CLI v2が対応。v1は未対応
- 設定ファイルはAWS CLIだけでなくAWS SDK全般で流用可能
- IAM Identity Centerはリージョナル・サービス
- IAM ユーザーのように永続的なアクセスキーは存在せず一時的な認証情報を利用
- 各アカウントへの操作はスイッチロールベース
- 一時認証情報は2段構成
- IAM Identity Centerの認証に対する一時認証情報(
aws sso-oidc create-token
) - この一時認証情報を利用して取得する、各アカウントへのスイッチロール用一時認証情報(
aws sso get-role-credentials
)
- IAM Identity Centerの認証に対する一時認証情報(
- セッション時間(デフォルト8時間)はIAM Identity Centerで管理。その間は各アカウント向けの一時認証情報はリフレッシュされる
AWS CLIのSSO向け設定
1. [必須]AWS CLI v2のインストール
AWS CLIはv2しかIAM Identity Centerに対応していません。
クライアント環境でバージョンチェックし、"aws-cli/2.*" と2以降であることを確認してください。
$ aws --version
aws-cli/2.7.24 Python/3.8.8 Linux/4.14.133-113.105.amzn2.x86_64 botocore/1.13
バージョンが1系(aws-cli/1.*
)だった場合、次のドキュメントに従って CLI v2をインストールして下さい。
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html
IAM Identity Centerに対応していないAWS CLI v1の出力例です。
$ aws --version
aws-cli/1.27.52 Python/3.10.8 Darwin/21.3.0 botocore/1.29.52
$ aws sso
Note: AWS CLI version 2, the latest major version of the AWS CLI, is now stable and recommended for general use. For more information, see the AWS CLI version 2 installation instructions at: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:
aws help
aws <command> help
aws <command> <subcommand> help
aws: error: the following arguments are required: operation
また、本記事では、AWS CLIがセッション機能に対応した v2.9 以降を対象とします。
2系であっても、古いバージョンをお使いの場合は、より新しいバージョンに更新してください。
2. ウィザード形式で設定ファイルを生成
本記事では、Identity Center directoryでユーザー管理しているものとします。
$ aws configure sso
を実行し、ウィザードに従って
- セッション名(Identity Centerを識別するため)
- スタートURL
- リージョン
などを指定してください。
なお、IAM Identity Centerは特定のIdPに依存しません。 外部IdPを利用している場合は、適宜読み替えてください。
~$ aws configure sso
SSO session name (Recommended): my-sso
SSO start URL [None]: https://d-1234.awsapps.com/start
SSO region [None]: us-east-1
SSO registration scopes [sso:account:access]:
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-1.amazonaws.com/ ← 認証用URL
Then enter the code:
ABCD-EFGH ← 認証コード
初期入力が終わると、クライアント環境でブラウザがIdentity Center認証用URLを認証コードとともに開くので、ユーザー名・パスワード等を入力します。
IAM Identity Centerとの認証が成功すると、操作先AWSアカウントを選択します。
~$ aws configure sso
SSO session name (Recommended): my-sso
SSO start URL [None]: https://d-1234.awsapps.com/start
SSO region [None]: us-east-1
SSO registration scopes [sso:account:access]:
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-1.amazonaws.com/
Then enter the code:
ABCD-EFGH
There are 2 AWS accounts available to you.
foo, web@example.com (11111111)
> bar, main@example.com (22222222)
AWSアカウントとロールを選択すると、プロファイルが作成されます。
~$ aws configure sso
SSO session name (Recommended): my-sso
SSO start URL [None]: https://d-1234.awsapps.com/start
SSO region [None]: us-east-1
SSO registration scopes [sso:account:access]:
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
https://device.sso.us-east-1.amazonaws.com/
Then enter the code:
ABCD-EFGH
There are 2 AWS accounts available to you.
Using the account ID 22222222
The only role available to you is: AdministratorAccess
Using the role name "AdministratorAccess"
CLI default client Region [ap-northeast-1]:
CLI default output format :
CLI profile name [AdministratorAccess-22222222]:
To use this profile, specify the profile name using --profile, as shown:
aws s3 ls --profile AdministratorAccess-22222222
メッセージに従い、プロファイルを指定してS3バケット一覧を表示してみましょう。
~$ aws s3 ls --profile AdministratorAccess-22222222
2022-11-28 21:14:50 your-bucket-name
sts::get-caller-identity
を呼ぶと、このAWSアカウントのロールにスイッチしていることがわかります。
~$ aws sts get-caller-identity --profile AdministratorAccess-22222222
{
"UserId": "AROXXXXXXXXX:test",
"Account": "22222222",
"Arn": "arn:aws:sts::22222222:assumed-role/AWSReservedSSO_AdministratorAccess_abcdef/test"
}
3. 生成された設定ファイルを確認
~/.aws/config
に IAM Identity CenterとAWSアカウント用の設定が追記されます。
この設定ファイルは、あWS CLIだけでなく、公式のAWS SDK全般で共通です。
~/.aws/config
[default]
region = ap-northeast-1
output = json
; AWSアカウント向け設定
[profile AdministratorAccess-22222222]
sso_session = my-sso
sso_account_id = 22222222
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json
; IAM Identity Center向け設定
[sso-session my-sso]
sso_start_url = https://d-1234.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access
プロファイル「AdministratorAccess-22222222」の sso_session
フィールドから、このAWSアカウントはセッション名 my_sso
で指定した Identity Center配下とわかります。
操作対象のAWSアカウントを増やすには、profile セクションの設定をコピーします。
[default]
region = ap-northeast-1
output = json
[profile AdministratorAccess-22222222]
sso_session = my-sso
sso_account_id = 22222222
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json
[profile AdministratorAccess-11111111]
sso_session = my-sso
sso_account_id = 11111111
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json
; IAM Identity Center向け設定
[sso-session my-sso]
sso_start_url = https://d-1234.awsapps.com/start
sso_region = us-east-1
sso_registration_scopes = sso:account:access
追加した新しいAWSアカウントに対して操作すると、AWS CLIが一時認証情報を暗黙的に取得します。
$ aws s3 ls --profile 設定を追記したアカウントのプロファイル
[オプション]IAM Identity Ceenterのセッションの有効期間を変更
IAM Identity Ceenterと認証すると、一時アクセスキー(OIDC トークン)が発行され、このアクセスキーを利用して、各AWSアカウントにスイッチロールするための一時認証情報を取得します。
このトークンが有効な間は各AWSアカウント向け一時認証情報もリフレッシュされ、失効すると、IAM Identity Ceenterとの再認証が求められます。
$ aws s3 ls --profile YOUR-PROFILE
Error when retrieving token from sso: Token has expired and refresh failed
デフォルトではこのセッション期間は8時間で、AWSコンソールのIAM Identity Center→Settings→Sessionから変更可能です。
IAM Identity Centerでの認証からスイッチロールまでの流れを確認
IAM Identity Centerを利用すると、ユーザーに対して永続的なアクセスキーの発行は不要で、IAM Identity Centerと認証したあと、操作対象のAWSアカウント・ロールに対する一時認証情報が発行されます。
この流れを確認します。
$ aws configure sso
のウィザードでAWSアカウント向けのプロファイルを作成すると、~/.aws
ディレクトリのファイル階層は以下のとおりです。
.aws/
├── cli
│ └── cache
│ └── 123.json
├── config
└── sso
└── cache
├── 456.json
└── 789.json
一連のフローをSSOサービスに限ってCloudTrailログと突き合わせると、IAM Identity Center関連では以下の順でAPIが呼ばれています。
SSO:Authenticate
(Identity Centerとの認証)SSO-OIDC:CreateToken
(AWSアカウント向け認証情報を発行するための一時アクセスキー発行)SSO:GetRoleCredentials
(AssumeRoleする一時認証情報発行)
1. IAM Identity Centerとの認証
ウィザードの入力情報をもとに、IAM Identity Centerと認証します。
このステップにおいて、後続の(特に次に呼び出される)SSO-OIDC:CreateToken
APIのリクエストパラメーターに必要な情報が返却されていると思われます。
具体的には
- clientId
- clientSecret
- refreshToken
などです。
.aws/sso/cache
ディレクトリには2種類のファイルがあります。
そのうち、accessToken
を含まない次の形式のファイルがこのステップの処理に相当すると思われます。
{
"clientId": "your-client-id",
"clientSecret": "xxx.yyyy.zzz-in-jwt-format",
"expiresAt": "2023-04-28T08:39:08Z",
"scopes": [
"sso:account:access"
]
}
SSO:Authenticate
はCloudTrailには出力されますが、ドキュメント化されていないAPIです。
2. AWSアカウント向け認証情報を発行するための一時アクセスキー発行
このAPIは、スイッチロールするための一時認証情報を要求するための一時アクセスキーを発行します。APIドキュメントには"Creates and returns an access token for the authorized client. The access token issued will be used to fetch short-term credentials for the assigned roles in the AWS account."とあります。
.aws/sso/cache
ディレクトリには2種類のファイルがあります。
そのうち、accessToken
を含む次の形式のファイルがこのAPIのレスポンスに相当します。
{
"startUrl": "https://d-123.awsapps.com/start",
"region": "us-east-1",
"accessToken": "your-access-token",
"expiresAt": "2023-01-30T09:41:21Z",
"clientId": "your-client-id",
"clientSecret": "secret.in.jwt",
"refreshToken": "your-refresh-token"
}
clientSecret
は JWT で HS384(HMAC using SHA-384) で署名されています。
3. AssumeRoleする一時認証情報発行
aws sso get-role-credentials
API を利用すると、操作対象のAWSアカウントのロールをassumeするための一時認証を取得できます。APIドキュメントには"Returns the STS short-term credentials for a given role name that is assigned to the user."とあります。
このAPIは従来の STS::AssumeRole API の IAM Identity Center 版とみなせます。
API呼び出し時には、操作対象のAWSアカウントID・ロールとともに、先程の SSO-OIDC:CreateToken
API で取得したアクセストークン(accessToken
)を渡します。
$ aws sso get-role-credentials \
--account-id 111111111111 \
--role-name AdministratorAccess \
--access-token "your-access-token" \
--region us-east-1
{
"roleCredentials": {
"accessKeyId": "your-access-key",
"secretAccessKey": "your-secret-access-key",
"sessionToken": "your-session-token",
"expiration": 1674899972000
}
}
返却されるroleCredentials
は、AWSマネコンの "Command line or programmatic access" で取得する一時認証情報と同等です。
この認証情報を環境変数に設定して利用することもできます。
$ export AWS_ACCESS_KEY_ID=AS...
$ export AWS_SECRET_ACCESS_KEY=your-secret-access-key
$ export AWS_SESSION_TOKEN=your-session-token
$ aws sts get-caller-identity --profile AdministratorAccess-111111111111
{
"UserId": "DUMMY:foo",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_AdministratorAccess_xxx/foo"
}
$ aws s3 ls
...
.aws/cli/cache
ディレクトリには、このAPIのレスポンスがキャッシュ化されています。
~$ ls -1 ~/.aws/cli/cache
123.json
~$ cat ~/.aws/cli/cache/123.json | jq .
{
"ProviderType": "sso",
"Credentials": {
"AccessKeyId": "aaa",
"SecretAccessKey": "bbb",
"SessionToken": "...",
"Expiration": "2023-01-30T09:42:53Z"
}
}
フォーマットが同じですね。
まとめ
AWS CLIはv2からIAM Identity Centerとシームレスに連携します。
IAM Identity Centerとの認証後にAWS CLI(SDK)用の一時認証情報が払い出され、従来のIAMユーザーに紐づくアクセスキーのような永続的な認証情報は存在しません。
一時認証情報は以下の2種類があります。
- AWSアカウントのIAMロールをassumeするための認証情報(
SSO:GetRoleCredentials
で取得) - 上記認証情報を取得するために利用される、IAM Identity Centerが払い出す認証情報(
SSO-OIDC:CreateToken
で取得)
なお、IAM Identity Centerと同じく、一時認証情報でAWS APIを呼び出すサービスとして、証明書で一時認証情報を取得するIAM Roles Anywhereがあります。システマティックに一時認証情報を取得できるため、AWSとのシステム連携に最適です。
参考
- AWS SSOを図解してみた | DevelopersIO
- AWS IAM Identity Center にセッション管理機能が追加されました | DevelopersIO
- Get temporary credentials for IAM Identity Center users with the AWS CLI
- Configuring the AWS CLI to use AWS IAM Identity Center (successor to AWS Single Sign-On) - AWS Command Line Interface
- sso — AWS CLI 2.9.18 Command Reference