AWSへアクセスする際は使用するIAMでは、ユーザー管理機能が提供されていますが、外部のIDプロバイダー(IdP)で管理されているユーザーにAWSへのアクセス許可を与えることが可能です。
IAMがサポートする外部IdPは以下の2つです。
- SAML 2.0 (Security Assertion Markup Language 2.0)
- OpenID Connect (OIDC)
外部IdPとしてAuth0を使用し、OpenID Connectでの連携を行う方法を紹介します。
設定手順
- Auth0にユーザー追加
- Auth0にアプリケーションを作成
- Identifierを取得
- IAMの外部IDプロバイダーを登録
- IAMロールを作成
Auth0にユーザー追加
Auth0の管理画面を開き、Auth0にユーザーを追加します。

Auth0にアプリケーションを作成
Applicationの管理画面へ移動します。Create Applicationボタンをクリックします。

任意のNameを入力し、アプリケーションのタイプとしてNativeを選択し、Createボタンをクリックします。

SettingsタブのDomainとClient IDをメモします。

Settingsタブの最下部にAdvanced Settingsセクションがあります。初期状態では折りたたまれてます。

Advanced Settingsセクションを開き、Grant Typesタブを選択します。Device Codeにチェックを入れ、Save Changesボタンをクリックします。

Identifierを取得
APIsメニューを選択し、Auth0 Management APIを選択します。

General SettingsセクションのIdentifierをコピーします。

IAMの外部IDプロバイダーを登録
ここからはAWSのマネジメントコンソールで操作します。
IAMの管理画面のIDプロバイダメニューに移動し、プロバイダを追加ボタンをクリックします。

プロバイダのタイプとしてOpenID Connectを選択し、プロバイダのURLに前の手順でメモしたDomainを入力します。
末尾に/を含めるように入力する必要があります ので注意してください。
入力したらサムプリントを取得ボタンをクリックします。

対象者に前の手順でメモしたClient IDを入力し、プロバイダを追加ボタンをクリックします。

IAMロールを作成
登録後のプロバイダの詳細画面を表示します。
ロールの割り当てボタンをクリックし、新しいロールを作成を選択して次へボタンをクリックします。
IAMロール作成画面に遷移します。

エンティティの種類やIDプロバイダーは自動で入力されます。Audienceを選択し、次のステップボタンをクリックします。

このさきは通常のIAMロール作成と変わりません。割り当てるポリシーを選択し、名前をつけてIAMロールを作成します。


以上で設定完了です。
AWS環境へアクセス
AWS環境へアクセスします。
CLIでアクセス
OAuth 2.0のDevice Authorization FlowにそってIDトークンを取得し、取得したIDトークンを使用してAWSの認証情報を取得します。
コマンドを順に実行していきます。
- 変数を定義
DOMAIN={ドメイン名}
CLIENTID={クライアントID}
SCOPE=openid
AUDIENCE={Identifier}
verification_uriを取得
curl --request POST \
--url "https://${DOMAIN}/oauth/device/code" \
--header "content-type: application/x-www-form-urlencoded" \
--data "client_id=${CLIENTID}" \
--data "scope=${SCOPE}" \
--data "audience=${AUDIENCE}"
{
"device_code": "QEZAmEcj4eFsElb6oh4WKSQp",
"user_code": "LBJX-WZVT",
"verification_uri": "https://dev-xyfgnyiti57ob5ja-oidc.us.auth0.com/activate",
"expires_in": 900,
"interval": 5,
"verification_uri_complete": "https://dev-xyfgnyiti57ob5ja-oidc.us.auth0.com/activate?user_code=LBJX-WZVT"
}
IDトークンを取得する際にはscpdeにopenidを指定する必要があります。
verification_uri_completeにブラウザでアクセス




- トークンを取得
DEVICECODE={verification_uriを取得した際のdevice_code}
curl --request POST \
--url "https://${DOMAIN}/oauth/token" \
--header "content-type: application/x-www-form-urlencoded" \
--data "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
--data "device_code=${DEVICECODE}" \
--data "client_id=${CLIENTID}"
{
"access_token": "",
"id_token": "",
"scope": "openid",
"expires_in": 86400,
"token_type": "Bearer"
}
- assume-role-with-web-identityを実行
IDTOKEN=...
aws sts assume-role-with-web-identity \
--role-arn {IAMロールのARN} \
--role-session-name session001 \
--web-identity-token ${IDTOKEN}
{
"Credentials": {
"AccessKeyId": "",
"SecretAccessKey": "",
"SessionToken": "",
"Expiration": ""
},
"SubjectFromWebIdentityToken": "",
"AssumedRoleUser": {
"AssumedRoleId": "",
"Arn": ""
},
"Provider": "",
"Audience": ""
}
aws sts assume-role-with-web-identityリクエストを実行する際にAWSの認証情報は不要です。
AWS CLIで使用するCredentialsの取得ができました。
CLIを実用的に使えるようにする
取得したCredentials情報を~/.aws/configに手作業でコピーしても良いですが、Credentialsは1時間で期限切れになるため面倒です。 外部スクリプトの結果を使用する仕組みとして用意されているcredential_processを使用する ことで実用的に使えるようにします。
IAM Roles Anywhereでもcredential_processの仕組みが使われています
外部スクリプトの結果として、以下のJSONフォーマットを返却することで、認証情報として利用ができます。
{
"Version": 1,
"AccessKeyId": "an AWS access key",
"SecretAccessKey": "your AWS secret access key",
"SessionToken": "the AWS session token for temporary credentials",
"Expiration": "ISO8601 timestamp when the credentials expire"
}
CLIを実用的に使えるようにする手順
まずは/oauth/tokenAPIのレスポンスをtoken.jsonとして保存します。
(一度使用したデバイスコードは再利用できないので、手順としてはもう一度/oauth/device/codeAPIから実行してください)
curl --request POST \
--url "https://${DOMAIN}/oauth/token" \
--header "content-type: application/x-www-form-urlencoded" \
--data "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
--data "device_code=${DEVICECODE}" \
--data "client_id=${CLIENTID}" > token.json
{
"access_token": "",
"id_token": "",
"scope": "openid",
"expires_in": 86400,
"token_type": "Bearer"
}
ファイルにIDトークンを保存しておくことで、任意のタイミングでAWSのCredentialsが取得できます。
aws sts assume-role-with-web-identity \
--role-arn {IAMロールのARN} \
--role-session-name session001 \
--web-identity-token `cat token.json | jq -r .id_token` > aws_credential.json
{
"Credentials": {
"AccessKeyId": "",
"SecretAccessKey": "",
"SessionToken": "",
"Expiration": ""
},
"SubjectFromWebIdentityToken": "",
"AssumedRoleUser": {
"AssumedRoleId": "",
"Arn": ""
},
"Provider": "",
"Audience": ""
}
ここまでできたらあとは~/.aws/configにcredential_processを追加します。
[default]
credential_process = jq '{"Version":1, "AccessKeyId":.Credentials.AccessKeyId, "SecretAccessKey":.Credentials.SecretAccessKey, "SessionToken":.Credentials.SessionToken, "Expiration":.Credentials.Expiration}' /home/ec2-user/aws_credential.json
aws_credential.jsonのパスは絶対パスで指定する必要があります。
これでAWSのCredentialsが使用でき、かつ、有効期限が切れた際にはIDトークンを使用してaws_credential.jsonを取得するコマンドを実行するだけで、Credentialsの更新が可能です。
マネジメントコンソールでアクセス
CLIで使用するCredentialsをもとにマネジメントコンソールへのアクセスURLを生成できます。
SESSIONとしてURLエンコードした文字列を生成します。
SESSION=`jq '{"sessionId":.Credentials.AccessKeyId, "sessionKey":.Credentials.SecretAccessKey, "sessionToken":.Credentials.SessionToken, }' /home/ec2-user/aws_credential.json | jq -r @uri`
federationAPIを実行し、SigninTokenを取得。
curl "https://signin.aws.amazon.com/federation?Action=getSigninToken&SessionDuration=3600&Session=${SESSION}"
{
"SigninToken": ""
}
SigninTokenをセットし、ブラウザで以下のURLにアクセスするとマネジメントコンソールにアクセスできます。
https://ap-northeast-1.signin.aws.amazon.com/federation?Action=login&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&SigninToken={SigninToken}
