なぜこの仕組みがあるのか
IAMのベストプラクティスには昔から「IAMユーザーを増やすな」がある。アクセスキーは漏れるし、退職者アカウントの棚卸しは漏れるし、パスワードポリシーの面倒は増える。認証情報は、配った瞬間から管理すべき負債になる。
そこで発想を逆にする。認証は、すでにユーザーを管理している場所(Google Workspace、Active Directory、GitHub…)にやらせて、AWSは「その認証結果を信じて、どの権限を渡すか」だけを判断する。この「外の認証を信じる」ための受け口がIAM IDプロバイダーだ。
外部IdPと信頼関係を張るという意味では、ADのドメイントラストと同じ発想になる。認証の実体は向こうにあり、こちらは署名の検証だけをする。
仕組み — 登場人物は3つ
- 外部IdP(Google、GitHub、AD FS…)— ユーザーやワークロードを認証し、トークン(OIDC)またはアサーション(SAML)を発行する
- IAM IDプロバイダー — 「このIdPが署名したトークンは信じる」という宣言。IdPの発行者情報を登録しておく
- IAMロール + STS — トークンを持ってきた相手に
AssumeRoleWithWebIdentity(OIDC)/AssumeRoleWithSAML(SAML)で一時クレデンシャルを発行する
ポイントは、最後に手に入るのが一時クレデンシャルであること。長命なアクセスキーはこのフローのどこにも生まれない。
実例 — このブログのデプロイがそれ
このブログはGitHub ActionsからS3へデプロイしているが、リポジトリのSecretsにアクセスキーは入っていない。ワークフローの認証部分はこれだけだ。
permissions:
id-token: write # GitHubにOIDCトークンの発行を許可
- name: Configure AWS credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_ARN }}
流れはこうなる。
- GitHubがワークフロー実行時にOIDCトークンを発行する。「このリポジトリの、このブランチの実行である」と署名付きで主張するトークンだ
- AWS側のIAM IDプロバイダー(
token.actions.githubusercontent.comを登録済み)がその署名を検証する - ロールのトラストポリシーが「このリポジトリからの引き受けなら許可」と判定する
- STSが短時間だけ有効なクレデンシャルを返し、
aws s3 syncが動く
漏れて困るものがリポジトリ側に存在しない。キーのローテーションという作業自体が消える。CI/CDでまだアクセスキーを使っているなら、置き換え先はこれ一択だと思っている。
似た名前のサービスとの使い分け
認証まわりはサービス名が似ていて混乱するが、「誰を認証したいのか」で切ると整理できる。
| 誰を認証したいか | 使うもの | 一言で |
|---|---|---|
| CI/CD・外部ワークロード | IAM IDプロバイダー + IAMロール | 機械のフェデレーション |
| 社員(コンソール/CLIへのSSO) | IAM Identity Center | 人間のSSO。マルチアカウントの入口 |
| 自作アプリのエンドユーザー | Cognito | アプリのユーザー基盤(サインアップ・MFA込み) |
STSはこの表に並ばない。どのパターンでも最後に一時クレデンシャルを発行しているのはSTSであり、対立候補ではなく全パターン共通のエンジンだ。
このあたりの見分けはSAP試験でも頻出で、判断軸はサービス別ノートの認証・認可パターンにまとめてある。
料金
IAM IDプロバイダー自体は無料。発行された一時クレデンシャルで使ったAWSサービスの料金だけがかかる。