業務システムのデプロイをGitHub Actions(GitHubが提供するCI/CD実行基盤)で自動化している現場では、AWSへの認証にIAMユーザーのアクセスキーをCI/CDのシークレットとして保存している構成がまだ残っています。本記事は、そうした構成を運用しているインフラ担当者やSRE、既存パイプラインの保守を任されているエンジニアに向けた内容です。アクセスキー方式からOIDC(OpenID Connect、外部サービスがトークンで身元を証明する仕組み)方式への移行を検討する際に、何を確認し、どこを変更すればよいかを整理しました。
長期間有効なアクセスキーをCI/CDに置く構成は、動くという意味では問題なく機能します。しかし、キーは漏えいした瞬間からパイプラインの外でも使える「使い回し可能な鍵」です。誤ってログに出力されたり、実行環境が侵害されたりすると、ローテーション(鍵の定期的な更新作業)が追いつくまで悪用され続けるリスクがあります。
OIDCで何が変わるのか
OIDCを使う構成では、GitHub Actionsのワークフローが実行されるたびに、GitHub側が署名付きの短命なIDトークンを発行します。このトークンをAWSのSTS(Security Token Service、一時的な認証情報を払い出すAWSのサービス)に提示し、AssumeRoleWithWebIdentityというAPIでIAMロールの一時セッションを取得する流れです。
重要なのは、AWSアカウント内に常駐する長期キーが一切存在しなくなる点です。取得したセッションはロールに設定した有効期限(デフォルトは1時間、最大でも設定次第)で自動的に失効します。漏えいしても悪用できる時間が極めて限定されます。
この仕組みを支える要素は6つに分けて理解すると整理しやすくなります。GitHub Actionsが発行元の身元を名乗るためのOIDCトークンを発行する「GitHub OIDCイシュア」、そのトークンの発行元を信頼すると宣言する「AWS IAM OIDCプロバイダー」、どのリポジトリ・ブランチからのトークンを信用するかを定義する「IAMロールの信頼ポリシー」、トークンを検証して一時認証情報を発行する「AWS STS」、そして発行後のロールが実際に何をできるかを定める「IAMパーミッションポリシー」です。
信頼ポリシーと権限ポリシーは役割が明確に分かれています。信頼ポリシーは「誰がこのロールを引き受けられるか」を決め、権限ポリシーは「引き受けた後に何ができるか」を決めます。信頼ポリシーをどれだけ絞り込んでも、権限ポリシーが広すぎれば最小権限の原則は崩れます。逆もまた同様です。
既存のアクセスキー運用とどう比較するか
日本の現場でもAnsibleやJenkinsのクレデンシャルストアにAWSアクセスキーを保管し、ローテーションをスプレッドシートや手順書で管理しているケースは珍しくありません。この運用との最大の違いは「鍵そのものを持ち運ぶかどうか」です。
アクセスキー方式は、キーという実体をシークレットストアに置き、漏えいや期限切れを人間(またはジョブ)が監視し続ける必要があります。OIDC方式は、信頼関係をAWS側のポリシーとして宣言するだけで、持ち運ぶ鍵自体が存在しません。ローテーション作業自体がなくなるため、運用コストの削減にも直結します。
AWSのSSO(シングルサインオン)やIAM Identity Centerを使った人間向けの一時認証と発想は近く、OIDCはそれをCI/CDのワークフロー単位に適用したものと捉えると理解しやすくなります。GitLab CIやCircleCIも同様のOIDC連携に対応しており、GitHub固有の仕組みではなく業界標準のパターンです。
導入手順の段階的な確認ポイント
実際に移行する場合、次の順序で確認すると迷いにくくなります。
- ワークフローのYAMLに
permissions: id-token: writeが宣言されているか(これがないとトークン要求自体が失敗する) - AWSアカウントにIAM OIDCプロバイダーが作成済みか(プロバイダーURLは
https://token.actions.githubusercontent.com、クライアントID(オーディエンス)はsts.amazonaws.com) - IAMロールの信頼ポリシーの
Conditionで、対象リポジトリとブランチ(または環境名)がsubクレームで絞り込まれているか - アタッチされている権限ポリシーが、そのワークフローが実際に呼ぶAWS APIだけに限定されているか
- ロールのセッション時間(
MaxSessionDuration)がジョブの実行時間に対して過剰に長くないか
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-deploy-role
aws-region: ap-northeast-1このYAML例はaws-actions/configure-aws-credentialsというGitHub公式提供のアクションを使い、role-to-assumeで引き受けるIAMロールのARNを指定する形です。実際に組み込む前には、必ずテスト用のAWSアカウントで信頼ポリシーと権限ポリシーの両方を検証してから本番に適用してください。
既存の大規模システムでは、複数のマイクロサービスごとに異なるIAMロールを用意しているケースもあります。その場合、信頼ポリシーのsubクレームをリポジトリ単位・ワークフロー単位で細かく分け、ロールの乱立を避けるために命名規則を先に決めておくと、後からの棚卸しが楽になります。
今日確認できること
移行の是非を判断する前に、まず現状把握から始めると進めやすくなります。
- 現在のCI/CDパイプラインでAWSアクセスキーをシークレットとして保存しているワークフローを棚卸しする
- IAMコンソールでそのアクセスキーに紐づくIAMユーザーの権限ポリシーを確認し、本当に必要な範囲か見直す
- GitHubリポジトリの設定でOrganizationレベルのOIDCプロバイダー作成権限があるか、インフラ担当チームに確認する
- Terraformなど既存のIaC(Infrastructure as Code)の仕組みでOIDCプロバイダーとIAMロールを管理できるか検討する
まとめ
GitHub ActionsからAWSへの認証は、長期的なアクセスキーよりOIDCによる短命な一時認証情報の方が、漏えい時の影響範囲を小さくできる構成です。既存システムへの導入は、まずIAM OIDCプロバイダーの作成、次に信頼ポリシーと権限ポリシーをリポジトリ・ワークフロー単位で分離するところから着手すると無理がありません。
本番導入前には、テスト用のAWSアカウントでプロバイダー設定・信頼ポリシーの条件・権限ポリシーの範囲を必ず検証してください。まずは自分のパイプラインで使っているシークレットの一覧を洗い出すところから始めてみてください。