AWS を複数のアカウントで運用していると、アカウントごとに IAM ユーザーとアクセスキーを作って ~/.aws/credentials に貼る、という運用になりがちです。 IAM Identity Center(旧名 AWS SSO)を使うと、アクセスキーを持たずに、ブラウザでログインするだけで複数アカウントの一時的な認証情報を取得できます。

この記事では、~/.aws/config に SSO の設定がある環境を例に、次の順で整理します。

  1. IAM Identity Center の登場人物と全体像
  2. 権限セットとアカウント割り当ての関係
  3. aws sso login の裏側(ログインの流れ)
  4. ~/.aws/config の読み方
  5. 日々の使い方
  6. トークンの有効期限と、つまずきやすい点

旧名の名残で、CLI のコマンドや設定項目は今でも sso という名前です(aws sso login、sso_start_url など)。 コマンドの出力例は説明用です。アカウント ID・ユーザー名・ハッシュ値は実際の値とは異なります。

IAM Identity Center とは#

複数の AWS アカウントへのサインインを、1 か所で管理する仕組みです。 「誰が」「どのアカウントで」「何ができるか」を Identity Center に登録しておくと、ユーザーはそこにサインインするだけで、許可されたアカウントとロールを選べます。

IAM ユーザー方式との違いは次のとおりです。

項目IAM ユーザー + アクセスキーIAM Identity Center
認証情報長期のアクセスキー(失効させない限り有効)一時的な認証情報(1〜12 時間で失効)
ユーザーの管理場所アカウントごとに IAM ユーザーを作るIdentity Center で 1 回だけ作る
MFAアカウントごとに設定サインイン時に 1 回
退職・異動時全アカウントで削除するIdentity Center で無効化すれば全アカウントに効く
キーの漏えいリスクファイルに平文で残る残るのは期限付きのトークンだけ

登場人物#

まず用語を押さえます。

用語意味
IAM Identity Center全体を管理するサービス。AWS Organizations と一緒に使う。リージョンを 1 つ選んで有効にする
ID ソースユーザーの出どころ。Identity Center 自身のディレクトリ、Active Directory、外部の IdP(Okta や Microsoft Entra ID など)から選ぶ
ユーザー / グループサインインする人と、そのまとまり
権限セット(Permission Set)「何ができるか」の定義。IAM ポリシーの束(AdministratorAccess、ReadOnlyAccess など)
割り当て(Assignment)「ユーザー(またはグループ)に、このアカウントで、この権限セットを与える」という紐づけ
AWS アクセスポータルサインイン後に、使えるアカウントとロールを一覧できる Web 画面。URL が start URL
start URLhttps://d-xxxxxxxxxx.awsapps.com/start の形式。CLI の設定にも使う

全体像: 誰が・何を・どこで#

管理者が行う設定は、次の 3 つを割り当てで結ぶだけです。

ID ソースIdentity Center / AD / 外部 IdPユーザー / グループ誰が権限セット何ができるかAWS アカウントどこでalice / dev-team などAdministratorAccessReadOnlyAccessOrganizations のメンバーアカウント割り当てユーザー × 権限セット × アカウント各アカウントに IAM ロールが自動で作られるAWSReservedSSO_AdministratorAccess_xxxxxxxxxxxxxxxxIdentity Center が管理するロール。IAM から手で編集しない

権限セットを割り当てると何が起きるか#

権限セットはそれ自体が IAM ロールではありません。アカウントに割り当てた時点で、そのアカウントに IAM ロールが作られます。

  • ロール名は AWSReservedSSO_<権限セット名>_<ハッシュ> になる
  • ロールの信頼ポリシーは、Identity Center からの引き受けだけを許可する
  • 権限セットを変更すると、割り当て先のすべてのアカウントでロールが更新される(再プロビジョニング)

つまり、ユーザーがサインインして選ぶ「アカウント + ロール」は、実体としてはこの AWSReservedSSO_... ロールを引き受けることです。

ログインの流れ#

aws sso login から、実際に AWS の API を呼べるようになるまでを順に追います。 ポイントは 認証情報が 2 段階になっている ことです。

  1. アクセストークン: Identity Center にサインインした証明。aws sso login で取得する
  2. ロールの認証情報: アカウント + ロールごとの一時的なキー。アクセストークンを使って、コマンド実行時に取得する
AWS CLIブラウザIdentity Center(OIDC / ポータル)AWS の API(S3 など)ログイン(1 回)コマンド実行ごと① クライアント登録と認可の開始② ブラウザで認可 URL を開く③ サインイン(ID・パスワード・MFA)④ 認可コード(localhost に戻る)⑤ コードをアクセストークンに交換⑥ アクセストークンを返す(~/.aws/sso/cache に保存)⑦ GetRoleCredentials(アクセストークン + アカウント ID + ロール名)⑧ ロールの一時的な認証情報⑨ その認証情報で署名したリクエスト

破線の矢印は、呼び出しへの返事です。

順番に見る#

ログイン(①〜⑥)

  1. CLI が Identity Center の OIDC エンドポイントに自分を登録し、認可を開始する(①)
  2. ブラウザが開き、ID ソースの認証画面が表示される(②③)。MFA が有効ならここで求められる
  3. 認可コードが CLI に渡され(④)、アクセストークンに交換される(⑤⑥)
  4. アクセストークンは ~/.aws/sso/cache/ に JSON で保存される

コマンド実行ごと(⑦〜⑨)

  1. aws s3 ls --profile Sandbox_Read のようにプロファイルを指定すると、CLI がキャッシュ済みのアクセストークンを使って GetRoleCredentials を呼ぶ(⑦)
  2. 指定したアカウントのロール AWSReservedSSO_ReadOnlyAccess_... の一時的な認証情報が返る(⑧)
  3. CLI は、その認証情報で署名したリクエストを送る(⑨)。取得した認証情報は ~/.aws/cli/cache/ に保存され、期限まで使い回される

ブラウザでログインするのは最初の 1 回だけです。アカウントやロールを切り替えても、アクセストークンは使い回されるので、ブラウザは開きません。

ブラウザが使えない環境(SSH 接続先など)では、認可コードを localhost に戻す方式(④)が使えません。 aws sso login --use-device-code を使うと、表示された URL とコードを、手元の PC のブラウザで入力する方式になります。

~/.aws/config の読み方#

SSO の設定は ~/.aws/config に書きます。次は、実際の設定を元にしたものです(アカウント ID と start URL は伏せています)。

# --- 共通セッション設定 ---
[sso-session my_sso]
sso_start_url = https://d-xxxxxxxxxx.awsapps.com/start
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access

# --- Sandbox_Terraform アカウント ---
[profile Sandbox_Admin]
sso_session = my_sso
sso_account_id = 111111111111
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[profile Sandbox_Read]
sso_session = my_sso
sso_account_id = 111111111111
sso_role_name = ReadOnlyAccess
region = ap-northeast-1
output = json

構造は「1 つの sso-session を、たくさんの profile が参照する」形です。

[sso-session my_sso]sso_start_urlsso_regionsso_registration_scopesサインイン先の情報(1 つだけ)[profile Sandbox_Admin]sso_account_id = Sandbox のアカウントsso_role_name = AdministratorAccess[profile Sandbox_Read]sso_account_id = Sandbox のアカウントsso_role_name = ReadOnlyAccess[profile workload_Read]sso_account_id = workload のアカウントsso_role_name = ReadOnlyAccess

項目の意味#

セクション項目意味
sso-sessionsso_start_urlAWS アクセスポータルの URL
sso_regionIdentity Center を有効にしているリージョン。後述の region とは別物
sso_registration_scopesCLI に与える権限の範囲。sso:account:access は「アカウントとロールの一覧取得・認証情報の取得」。これを指定すると、トークンを自動で更新できる
profilesso_session参照する sso-session の名前
sso_account_idログイン先の AWS アカウント ID
sso_role_nameそのアカウントで使う権限セットの名前
regionAPI を呼ぶリージョン(Identity Center のリージョンとは無関係)
output出力形式

設定の工夫が見える部分#

  • プロファイル名は「アカウント名_権限」 になっている。xxx_Admin と xxx_Read を使い分けられる
  • 全プロファイルが同じ my_sso を参照しているので、ログインは my_sso に対して 1 回で済む
  • 権限セットは同じ AdministratorAccess / ReadOnlyAccess を全アカウントに揃えている。名前で何ができるか分かる

sso-session を使わない古い書き方(各プロファイルに sso_start_url と sso_region を直接書く)もありますが、 トークンの自動更新ができず、プロファイルごとにログインが必要になります。新しく書くなら sso-session 形式にしてください。

使い方#

初回の設定#

~/.aws/config は手で書けますが、対話形式で作ることもできます。

aws configure sso

start URL、リージョン、アカウント、ロールを順に聞かれます。アカウントとロールは、ログイン後に選択肢が表示されます。 sso-session の名前を聞かれたら、既存の名前(ここでは my_sso)を入力すると、同じセッションを使うプロファイルが追加されます。

ログインと確認#

Command

aws sso login --sso-session my_sso

ブラウザが開くので、サインインして「許可」を押します。--sso-session で指定すれば、そのセッションを使うすべてのプロファイルがまとめてログイン状態になります。

Command

aws sts get-caller-identity --profile Sandbox_Read

Output

{
    "UserId": "AROAXXXXXXXXXXXXXXXXX:alice",
    "Account": "111111111111",
    "Arn": "arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_ReadOnlyAccess_0123456789abcdef/alice"
}

Arn に AWSReservedSSO_ReadOnlyAccess_... が出ていれば、設定どおりに動いています。末尾の alice が、サインインしたユーザー名です。 CloudTrail にもこの名前で記録されるので、誰が操作したかを追えるのも利点です。

プロファイルの指定方法#

Command

# コマンドごとに指定する
aws s3 ls --profile Sandbox_Read

# シェルの間は固定する
export AWS_PROFILE=Sandbox_Read
aws s3 ls

Terraform や AWS SDK も、AWS_PROFILE を見て同じ設定を使います。

AWS_PROFILE=Sandbox_Admin terraform plan

Admin と Read を使い分ける#

この設定では、ほとんどのアカウントに _Admin と _Read の 2 種類があります。

  • 普段の確認・調査は _Read: 誤ってリソースを消す、変える心配がない
  • 変更するときだけ _Admin: コマンドごとに --profile で明示する

AWS_PROFILE に _Admin を入れたままにすると、別の作業でも管理者権限で動いてしまいます。常用は _Read にしておくのが安全です。

ログアウト#

Command

aws sso logout

キャッシュされたアクセストークンと、ロールの認証情報を削除します。共有の端末で作業したあとは実行してください。

有効期限: 2 つの時計がある#

ログインが切れるタイミングは、2 種類の期限で決まります。

① Identity Center のセッション期間(既定 8 時間、管理者が変更できる)この間は、アクセストークンが更新され続ける。切れたら aws sso login が必要② ロールの認証情報権限セットのセッション期間(既定 1 時間)② ロールの認証情報切れたら自動で取り直し② ロールの認証情報切れたら自動で取り直し…
期限決まる場所既定値切れるとどうなる
① アクセストークン(Identity Center のセッション)Identity Center の設定8 時間(15 分〜90 日で変更可)aws sso login をやり直す
② ロールの認証情報権限セットの「セッション期間」1 時間(最大 12 時間)CLI が①を使って自動で取り直す(操作不要)

つまり、日常で意識するのは①だけです。朝に 1 回 aws sso login すれば、その日は使い続けられるというのが、既定値での感覚です。

つまずきやすい点#

Token has expired and refresh failed と出る ①の期限が切れています。aws sso login --sso-session my_sso をやり直してください。

The SSO session associated with this profile has expired or is otherwise invalid 同じく①の期限切れです。aws sso login で解決します。

ブラウザが開かない・開けない(SSH 接続先や WSL など) aws sso login --use-device-code を使います。必要なら --no-browser も付けて、表示された URL を手元のブラウザで開き、コードを入力します。

sso_region と region を混同する sso_region は Identity Center を有効にしたリージョン(ログインに使う)、region は s3 や ec2 などを呼ぶリージョンです。 別々の値でも問題ありません。

SSO に対応していない古いツールで使いたい 一時的な認証情報を環境変数に書き出せます。

eval "$(aws configure export-credentials --profile Sandbox_Read --format env)"

その端末のセッションだけで有効な環境変数が設定されます。ファイルには残りません。

プロファイル名が長くて打ちにくい シェルの補完か、AWS_PROFILE の切り替え用の関数を用意すると楽になります。

まとめ#

  • IAM Identity Center は、ユーザー × 権限セット × アカウント の割り当てで、複数アカウントへのアクセスを一元管理する仕組み
  • 割り当てると、各アカウントに AWSReservedSSO_... の IAM ロールが作られ、サインインしたユーザーはそのロールを引き受ける
  • aws sso login でアクセストークンを取り、コマンド実行時にそれを使ってロールの一時認証情報を取る。2 段階になっている
  • ~/.aws/config は、1 つの sso-session を複数の profile が参照する構造にする。ログインは 1 回で済む
  • 普段は _Read、変更するときだけ _Admin。アクセスキーはどこにも置かない

参考#