IAMパスワードなしでAWS Management Consoleにログインする方法

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

西澤です。AWSを運用していると、AWS Management Console用のIAMパスワードと、APIアクセス用のアクセスキーの2つを管理することになるケースが多くなると思いますが、管理は片方だけで済ませたいものですよね。IAMパスワードを発行しないまま、アクセスキーだけでAWS Management Consoleにログインする方法があることをご存知でしょうか?

過去に書いた記事の焼き直しではあるのですが、丁度ご質問をいただいたこともあり、その機能を改めてご紹介してみようと思います。

IAMパスワードとアクセスキー

IAMユーザには、そのユーザに紐付くパスワードとアクセスキーを発行することが可能です。通常の使い方では、下記のようにご利用されている方がほとんどかと思います。1つのアカウントに対して、2つの認証情報を管理することになる為、定期的な更新も考えると、非常に手間がかかります。

認証情報 通常の使い方
パスワード AWS Management Consoleへのログインに利用
アクセスキー APIアクセス(AWS SDK,AWS CLI)に利用

IAMパスワードなしでAWS Management Consoleログインを実現する方法

IAMパスワードを利用せずに、AWS Management Consoleへのログイン方法には、以下のような方法がありますが、これらの方法を用いる為には仕掛けを事前に準備する必要があり、必要な時にすぐに利用できる訳ではありません。

  • SAML等のIDプロバイダーを利用したフェデレーションログイン
  • AWS Directory Serviceを利用したSSO

そこで、今回は一時クレデンシャルを利用したAWS Management Consoleへのログイン方法をご紹介します。

一時クレデンシャルを利用したAWS Management Consoleログイン用URL作成の流れ

AWS Management Consoleログイン用URLを作成する為には、下記の手続きが必要となります。

  1. 一時的なセキュリティ認証情報を取得
    • GetFederationTokenAssumeRole等を利用
    • アクセスキー、シークレットアクセスキー、トークンの3セットを入手
  2. 取得した情報からセッション文字列を生成
  3. セッション文字列をURLエンコード
  4. AWSフェデレーションエンドポイントにリクエストを送信してサインイントークンを取得
  5. ログイン用URLを作成

というところの詳しい説明とサンプルスクリプト(Python,Java,Ruby)が公式ドキュメントに掲載されています。

FederatedユーザによるAWS Management Consoleログイン

AssumeRole APIを利用したログインURL作成も、ほぼ同じ流れとはなりますので、今回はFederatedユーザによるログインURL生成をやってみます。アクセスキーを有したIAMユーザそのものによるAWS Management Consoleへのログインとは正確には異なるのですが、Federatedユーザに同等の権限を移譲することで、一時的なAWS Managment ConsoleへのログインURLを生成することができます。Federatedユーザは、事前準備なし(IAMロール作成不要)で利用したい時にだけ一時的な権限を発行することができる為、アクセスキーがあればすぐに試すことができます。しかも、利用するのは一時クレデンシャルなので、有効期限(90m〜36h、デフォルト12h)が切れれば自動的に使えなくなるというところも、セキュリティ観点で嬉しいですね。

Federatedユーザへの権限移譲イメージ

Federatedユーザには、それを要求したユーザ(sessionIssuer)の権限の一部を割り当てることができます。今回は、要求ユーザと同等の権限でAWS Management Consoleにアクセスしたいので、全権限を移譲してしまえば良いでしょう。逆に要求ユーザ以上の権限をFederatedユーザに割り当てることはできません(※リソースベースで割り当てられた権限を除く)。

前提条件

要求するユーザ(sessionIssuer)には、GetFederationToken権限が必要となります。必要な仕掛けはこれだけで大丈夫です(といっても通常は、AdminやPowerUser以外に敢えて付けてはいないと思いますので、事前に必要な仕掛けが完全にゼロとは言えないです、すみません)。

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Action": "sts:GetFederationToken",
        "Resource": "*"
    }]
}

Federatedユーザ用のログインURL生成スクリプト

公式ドキュメントには無かったので、AWS CLIとbashだけでログインURLを生成するスクリプトを作りました(前に作ったものをアップデートしました)。

AWS CLI版

認証情報設定済みのAWS CLI環境(JMESPath=jp.py含む)とbash、curlがあれば動くと思います。

#!/bin/bash
set -e

# urlencode用のfunction定義
urlencode() {
  local length="${#1}"
  for (( i = 0; i < length; i++ )); do
    local c="${1:i:1}"
    case $c in
      [a-zA-Z0-9.~_-]) printf "$c" ;;
      *) printf '%%%02X' "'$c"
    esac
  done
}

# Federatedユーザ定義(今回はsessionIssuertと同等=全権限を付与)
FED_USER=feduser # 任意の名前で動作するが、要求元ユーザを明示することが望ましい
POLICY_FILE=policy_all_allow.json
cat << EOF > ${POLICY_FILE}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}
EOF

# FederationToken取得(有効期間を調節したい場合には、--durationオプションを変更)
FEDERATION_TOKEN=$(aws sts get-federation-token --name ${FED_USER} --policy file://./${POLICY_FILE} --duration-seconds 3600)

# セッション文字列生成
SESSION_ID=$(echo ${FEDERATION_TOKEN} | jp.py "Credentials.AccessKeyId" | tr -d "\"")
SESSION_KEY=$(echo ${FEDERATION_TOKEN} | jp.py "Credentials.SecretAccessKey" | tr -d "\"")
SESSION_TOKEN=$(echo ${FEDERATION_TOKEN} | jp.py "Credentials.SessionToken" | tr -d "\"")

# 一時ファイル削除
rm ${POLICY_FILE}

# SigninToken取得
JSON_FORMED_SESSION=$(echo "{\"sessionId\":\"${SESSION_ID}\",\"sessionKey\":\"${SESSION_KEY}\",\"sessionToken\":\"${SESSION_TOKEN}\"}")
SIGNIN_URL="https://signin.aws.amazon.com/federation"
GET_SIGNIN_TOKEN_URL="${SIGNIN_URL}?Action=getSigninToken&SessionType=json&Session=$(urlencode ${JSON_FORMED_SESSION})"
SIGNIN_TOKEN=$(curl -s "${GET_SIGNIN_TOKEN_URL}" | jp.py "SigninToken" | tr -d "\"")

# LOGIN URLの出力
ISSUER_URL="https://mysignin.internal.mycompany.com/"
CONSOLE_URL="https://console.aws.amazon.com/"
LOGIN_URL="${SIGNIN_URL}?Action=login&Issuer=$(urlencode ${ISSUER_URL})&Destination=$(urlencode ${CONSOLE_URL})&SigninToken=$(urlencode ${SIGNIN_TOKEN})" && echo ${LOGIN_URL}

生成された長いURLでアクセスしてみましよう。要求したユーザとほぼ同じ権限でAWS Management Consoleの操作ができるはずです。

AssumedRole環境ではGetFederationTokenは発行できませんのでご注意ください。その場合は、素直にAssumeRole APIから取得した一時クレデンシャルを使いましょう。

A client error (AccessDenied) occurred when calling the GetFederationToken operation: Cannot call GetFederationToken with session credentials

Powershell版

こちらを参考にやってみてください。

まとめ

本来は自前で認証用のアプリケーションを作成する為の機能だと思いますが、運用ツールとしても十分に使えると思います。このような便利な機能を組み合わせて上手にAWSを使って行きましょう。

どこかの誰かのお役に立てば嬉しいです。