IAM IDプロバイダー — AWSにユーザーを作らないという設計

IAM IDプロバイダーが解決するのは「認証情報を配ると負債になる」問題。認証は外でやり、AWSは認可だけやるという設計思想を、このブログのデプロイ(GitHub Actions OIDC)を実例に整理する。

なぜこの仕組みがあるのか

IAMのベストプラクティスには昔から「IAMユーザーを増やすな」がある。アクセスキーは漏れるし、退職者アカウントの棚卸しは漏れるし、パスワードポリシーの面倒は増える。認証情報は、配った瞬間から管理すべき負債になる。

そこで発想を逆にする。認証は、すでにユーザーを管理している場所(Google Workspace、Active Directory、GitHub…)にやらせて、AWSは「その認証結果を信じて、どの権限を渡すか」だけを判断する。この「外の認証を信じる」ための受け口がIAM IDプロバイダーだ。

外部IdPと信頼関係を張るという意味では、ADのドメイントラストと同じ発想になる。認証の実体は向こうにあり、こちらは署名の検証だけをする。

仕組み — 登場人物は3つ

  1. 外部IdP(Google、GitHub、AD FS…)— ユーザーやワークロードを認証し、トークン(OIDC)またはアサーション(SAML)を発行する
  2. IAM IDプロバイダー — 「このIdPが署名したトークンは信じる」という宣言。IdPの発行者情報を登録しておく
  3. 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 }}

流れはこうなる。

  1. GitHubがワークフロー実行時にOIDCトークンを発行する。「このリポジトリの、このブランチの実行である」と署名付きで主張するトークンだ
  2. AWS側のIAM IDプロバイダー(token.actions.githubusercontent.com を登録済み)がその署名を検証する
  3. ロールのトラストポリシーが「このリポジトリからの引き受けなら許可」と判定する
  4. 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サービスの料金だけがかかる。