
GitHub ActionsからAWSへ、長期キーを置かないOIDC設定

GitHub ActionsからAWSへ長期アクセスキーなしでデプロイするには、GitHubのOIDCトークンでAWSのIAMロールを引き受ける。実行時に短期認証情報を取得し、ロールの信頼ポリシーで利用元のリポジトリとブランチを限定する構成だ。
切り替えは、デプロイ元と必要なAWS権限の確認、OIDCプロバイダーの登録、IAMロールの作成、workflowの変更、動作確認、旧キーの撤去の順に進める。旧キーを無効化する前に、OIDCによる認証とデプロイが両方通ることを確かめる。
デプロイ元とロールの権限を決める
まず、GitHubの組織名とリポジトリ名、デプロイを許可するブランチ、対象のAWSアカウントとリージョンを確定する。以下はmainブランチから実行する場合の例で、実際の設定では自分の値に置き換える。workflowの起動条件だけでなく、AWS側の信頼条件にも同じデプロイ元を指定する。
IAMロールには、誰が引き受けられるかを決める信頼ポリシーと、引き受けた後に何を操作できるかを決める権限ポリシーがある。リポジトリを厳密に指定しても、ロールに広い権限を付ければ、許可されたジョブが不要なAWSリソースまで操作できる。デプロイに使う操作と対象リソースを先に洗い出し、その範囲の権限をロールへ付ける。
GitHubのOIDCプロバイダーをIAMに登録する
AWS IAMの「IDプロバイダー」でOpenID Connectを選び、プロバイダーURLに https://token.actions.githubusercontent.com、対象者に sts.amazonaws.com を設定する。後者はaws-actions/configure-aws-credentialsを使う場合の値だ。登録後に表示されるプロバイダーのARNを控え、ロールの信頼ポリシーでFederatedプリンシパルとして指定する。
続いてIAMでロールを作成し、信頼されたエンティティの種類を「ウェブアイデンティティ」にする。登録したGitHubのプロバイダーと対象者を選び、画面に組織、リポジトリ、ブランチの入力欄があれば、許可する値をそれぞれ指定する。リポジトリやブランチを空欄にするとワイルドカードになる場合があるため、作成後に信頼ポリシーを開いて条件を確認する。
ロールに付ける権限ポリシーはデプロイ先に合わせて作る。たとえば特定のS3バケットへ成果物を配置するなら、必要なS3操作と対象バケットのARNを指定する。認証後のデプロイ操作だけが拒否される場合は、信頼ポリシーではなく、この権限ポリシーや対象リソースの指定を確認する。
信頼ポリシーのsubをリポジトリとブランチに絞る
AWSのIAMロール作成手順は、GitHubを信頼するロールにsub条件を設け、対象のリポジトリやブランチを限定するよう勧めている。ロールの信頼ポリシーではPrincipalのFederatedに登録済みプロバイダーのARN、Actionに sts:AssumeRoleWithWebIdentity を設定する。ConditionのStringEqualsには、token.actions.githubusercontent.com:aud が sts.amazonaws.com と一致する条件と、token.actions.githubusercontent.com:sub が許可するデプロイ元と一致する条件を入れる。
名前だけを使うsub形式なら、mainブランチを許可する値は repo:ORG/REPO:ref:refs/heads/main となる。ORGとREPOは実際の組織名とリポジトリ名に置き換える。組織名だけを残したワイルドカードや、repo:ORG/REPO:* のような条件は、許可する実行元を広げる。ブランチを限定したいロールには、該当するsubの完全一致を使う。
GitHubのAWS向けOIDC設定手順によると、2026年7月15日より後に作成されたリポジトリや固定ID形式を有効にしたリポジトリでは、subに所有者とリポジトリのIDが含まれる。形式は repo:ORG@OWNER_ID/REPO@REPO_ID:ref:refs/heads/main で、名前だけの条件とは一致しない。既存の信頼ポリシーを流用するときも、対象リポジトリが発行する形式に合わせてsubを書き換える。
ジョブにGitHubのenvironmentを指定する場合、subにはブランチ参照の代わりに environment:ENVIRONMENT_NAME が入る。したがって、ブランチ形式のsubを信頼ポリシーに残したままでは、そのジョブはロールを引き受けられない。environment形式へ条件を合わせるとともに、GitHub側のenvironment保護ルールでデプロイを許可するブランチやタグを制限する。
workflowを短期認証情報へ切り替える
デプロイ用ジョブのpermissionsに id-token: write を設定する。これはGitHubのOIDCトークンを要求する権限であり、AWSリソースへの書き込み権限ではない。リポジトリをチェックアウトするジョブなら contents: read も指定する。mainへのpushでデプロイする例では、workflowの起動条件もmainに限定する。
configure-aws-credentialsの設定例では、認証ステップに aws-actions/[email protected] を使い、withの role-to-assume にIAMロールのARN、aws-region に対象リージョンを指定している。この構成では、アクションがGitHubのOIDCトークンを使ってロールを引き受け、後続ステップで利用するAWS認証情報を設定する。ロールARNは秘密のアクセスキーではないため、それを渡すためだけに旧キーを残す必要はない。
切り替えるジョブから、旧方式の aws-access-key-id と aws-secret-access-key の入力を取り除く。Secretsから AWS_ACCESS_KEY_ID や AWS_SECRET_ACCESS_KEY を渡しているenv設定も外す。共通workflowや別の認証ステップが同じキーを読み込んでいないか確認し、検証対象のジョブが旧方式へ依存しない状態にする。
認証ステップの直後には aws sts get-caller-identity を実行し、その後に既存のデプロイコマンドを置く。この順なら、ロールの引き受けに失敗したのか、引き受け後のAWS操作が拒否されたのかを分けて判断できる。設定例のORG、REPO、ロールARN、リージョンは一組として照合し、異なるAWSアカウントのロールを指定しないようにする。
認証結果とデプロイ結果を分けて確認する
許可したブランチからworkflowを実行し、configure-aws-credentialsのステップが成功するか確認する。続く get-caller-identity の結果では、想定したAWSアカウントと引き受けたロールを照合する。ここまで成功してデプロイ操作が拒否されるなら、必要なAWS操作や対象ARNがロールの権限ポリシーに含まれているかを見る。
AssumeRoleWithWebIdentityが拒否された場合は、登録したプロバイダー、対象者の sts.amazonaws.com、ロールARN、信頼ポリシーのsubを順に照合する。特にsubは、所有者とリポジトリの固定IDの有無、ブランチ名、environmentの使用によって形式が変わる。通すためにワイルドカードへ広げるのではなく、実際のデプロイ元に一致する条件を設定する。
デプロイが成功しても、旧アクセスキーが別のステップから読み込まれていれば移行の確認にはならない。workflow内のSecrets参照と認証アクションの入力を見直し、OIDCで引き受けたロールによって必要な処理が完了したことを確認する。
旧アクセスキーとSecretsを撤去する
OIDCだけで認証とデプロイが通ったら、旧キーを使用する他のジョブやシステムがないか調べる。対象のIAMアクセスキーを無効化し、その状態でもデプロイできることを確かめてからキーを削除する。先に無効化する手順なら、見落とした依存先があった場合に切り分けられる。
最後に、GitHubのリポジトリ、environment、組織に保存した対応するSecretsを削除し、workflowに残る旧キー名や参照も消す。同じキーを複数の場所に登録していた場合は、各保存先と利用元を照合する。次にブランチやenvironmentの構成を変える際は、その変更に合わせてsub条件も更新する。
関連記事:
関連記事
ニュースレターを購読
Web3、AI、暗号資産の最新ニュースを受信箱にお届けします。




