私はAWSマネジメントコンソールへのアクセスにGMailの認証を利用したり、あるいはLMS (Learning Management System) の認証を利用してIAMロールを活用してアクセスしています。
いずれも、使用しているのはOpenID ConnectのID Tokenです。
GMailの場合のIAMロールの信頼関係は次のようにそのまま設定できます。IAMでサポートされていない場合は、IDプロバイダを登録して信頼関係を設定します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "accounts.google.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"accounts.google.com:aud": "xxxxxx-xxxxx.apps.googleusercontent.com"
}
}
}
]
}
IAMロールの信頼関係があれば、そのIAMロールにAssumeRoleWithWebIdentityによって一時的な認証情報が得られます。次のコードブロックは、Google Apps ScriptでAssumeRoleWithWebIdentityを実行するコードです。
const role_arn = encodeURIComponent(ROLE_ARN);
const role_session_name = encodeURIComponent(EMAIL_ADDRESS);
const token = encodeURIComponent(ID_TOKEN);
const formData = `Action=AssumeRoleWithWebIdentity&RoleSessionName=${role_session_name}&RoleArn=${role_arn}&WebIdentityToken=${token}&DurationSeconds=3600&Version=2011-06-15`;
const res = UrlFetchApp.fetch('https://sts.amazonaws.com/', {
'method': 'post',
'payload': formData
});
const xml = XmlService.parse(res.getContentText());
const root = xml.getRootElement();
const ns = root.getNamespace();
const assumeRoleWithWebIdentityResult = root.getChild('AssumeRoleWithWebIdentityResult', ns);
const credentials = assumeRoleWithWebIdentityResult.getChild('Credentials', ns);
const roleCreds = {
'sessionId': credentials.getChildText('AccessKeyId', ns),
'sessionKey': credentials.getChildText('SecretAccessKey', ns),
'sessionToken': credentials.getChildText('SessionToken', ns)
};
AWS STS (Security Token Service) の AssumeRoleWithWebIdentity により取得した認証情報を使って SigninToken を https://signin.aws.amazon.com/federation エンドポイントを使用して取得します。Google Apps Scriptのコード例は次のコードブロックのようになります。
const req = "https://signin.aws.amazon.com/federation" +
"?Action=getSigninToken" +
"&SessionDuration=43200" +
"&Session=" +
encodeURIComponent(JSON.stringify(roleCreds));
const res = UrlFetchApp.fetch(req);
const signinToken = JSON.parse(res.getContentText())['SigninToken'];
最後にAWSマネージメントコンソールに遷移すると引き受けたIAMロールでアクセスできます。Google Apps Scriptの例は次のコードブロックのようになります。
const distination = encodeURIComponent('https://console.aws.amazon.com');
const redirectUrl = `https://signin.aws.amazon.com/federation?Action=login&Issuer=gmail.com&Destination=${distination}&SigninToken=${signinToken}`;
おわりに
この記事では、Google Apps Scriptを使ったコード例で説明しました。直接 STS の AssumeRoleWithWebIdentity を呼び出した場合は XML でレスポンスが返されました。
LMS から連携される ID_TOKEN を利用して AWSマネジメントコンソール にアクセスするためのコードは AWS SDK を利用しているため、レスポンスが XML であることを意識する必要はありません。
参考までに nakanoshima.dev コミュニティの登壇スライドを共有します。