Logo
言語日本語

GitHub Actions から安全に AWS の IAM ロールを引き受けるベストプラクティス

2025-08-082025-08-26
Icon of ITITIcon of AWSAWSIcon of GitHubGitHub
OGP GitHub Actions から安全に AWS の IAM ロールを引き受けるベストプラクティス

GitHub Actions にて CI/CD を構築しているとき、AWS リソースにアクセスしたくなるときがありますよね?そのような時には、OpenID Connect (OIDC) を利用したフローにて IAM ロールを引き受けることが推奨されます。

本記事では、IAM ロール引き受けまでのフローと具体的な手順をご紹介いたします!

ロール引き受け方法

まず、IAM ロールを引き受ける方法を考える中で、すべての選択肢を把握しておく必要があります。IAM ロールの引き受け方法は AWS ドキュメント にまとめられています。

この中で、AWS 外部で IAM ロールを引き受ける際には OpenID Connect (OIDC) が最も堅実な選択肢です。

OIDCを使用する利点

OpenID Connect (OIDC) を使用して GitHub Actions から AWS IAM ロールを引き受けることには、いくつかの重要な利点があります。

  • シークレットの静的保存が不要: 長期的な AWS アクセスキーやシークレットを GitHub シークレットに保存する必要がありません。これにより、認証情報漏洩のリスクが大幅に軽減されます。
  • 認証情報のローテーションが自動化: OIDC を使用すると、一時的な認証情報が自動的に生成されるため、手動での認証情報の更新やローテーションが不要になります。
  • きめ細かいアクセス制御: IAM 信頼ポリシーを使用して、特定のリポジトリ、ブランチ、タグなどに基づいてアクセスを制限できるため、最小権限の原則に従ったセキュリティ設計が可能です。
  • 監査性の向上: すべてのアクションは特定の GitHub ワークフローに関連付けられており、AWS CloudTrail でのロギングと監査が容易になります。
  • 管理の簡素化: 複数のサービスアカウントやアクセスキーを管理する代わりに、信頼関係に基づく連携を設定するだけで済みます。

これらの利点により、OIDC は GitHub Actions と AWS の統合における現在のベストプラクティスとなっています。

今回も OIDC によるロール引き受けを使用します。

ロール引き受けまでのフロー

今回ご紹介する GitHub Actions でのロール引き受け手順は、AWS IAM の Web Identity の一般的な流れと同じです。

mermaid

sequenceDiagram
    participant Workflow as GitHub Workflow
    participant OIDCProvider as GitHub OIDC Provider
    participant AWSSTS as AWS STS
    participant AWSService as AWS Service

    Note over Workflow: 実行環境からIDトークンを要求
    Workflow->>OIDCProvider: リポジトリ情報などを含めてリクエスト
    OIDCProvider-->>Workflow: JWT形式のIDトークンを発行

    Workflow->>AWSSTS: AssumeRoleWithWebIdentity(IDトークンを添付)
    AWSSTS->>OIDCProvider: JWKs取得
    AWSSTS->>AWSSTS: JWT署名・iss・aud・exp・sub等を検証
    AWSSTS->>AWSSTS: IAMロールの信頼ポリシーと照合
    AWSSTS-->>Workflow: 一時認証情報を返却

    Workflow->>AWSService: 一時認証情報でアクセス
    AWSService-->>Workflow: レスポンス

手順

  1. Identity Provider の作成
  2. IAM ロールの作成
  3. GitHub Actions の設定ファイルの作成

Identity Provider の作成

IAM > Identity providers から新しい Identity providers を作成します。入力する値は固定値です。

  • Provider URL: https://token.actions.githubusercontent.com
  • Audience: sts.amazonaws.com

IAM ロールの作成

マネジメントコンソールから IAM ロールを作成する場合、以下のような設定にします。

  • Identity provider: 作成した IdP を選択

IdP を選択すると、クレーム情報の入力ができます。sub の部分はユーザー名・リポジトリ名・ブランチ名に分かれて入力補助が出ます。

  • Audience: sts.amazonaws.com を選択
  • GitHub organization: 組織名またはユーザー名
  • GitHub repository: リポジトリ名 (任意)
  • GitHub branch: ブランチ名 (任意)

信頼ポリシーは以下のようになります。IaC で作成するときなどの参考にしてください。

Trusted entities

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::{アカウントID}:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                },
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:{ユーザー・組織名}/{リポジトリ名}:*"
                }
            }
        }
    ]
}

GitHub Workflows の作成

aws-actions/configure-aws-credentials を使用することで、自動でクレデンシャルを取得しロールを引き受けることができます。

なお、今回は Rust でテストコードを用意しているため、Rust のための GitHub Actions が例に含まれています。

yaml

name: Fetch SSM Parameter

on:
  workflow_dispatch:

env:
  AWS_REGION: "ap-northeast-1"

permissions:
  id-token: write
  contents: read

jobs:
  test:
    name: Unit Test
    runs-on: ubuntu-latest
    steps:
      - name: Clone Repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.IAM_ROLE_ARN }}
          role-session-name: samplerolesession
          aws-region: ${{ env.AWS_REGION }}

      - name: Setup Rust Toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1

      - name: Run
        run: cargo run

今回使用した Rust のコード例

src/index.ts

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;

    let client = aws_sdk_ssm::Client::new(&config);

    let value = client
        .get_parameter()
        .name("/message")
        .send()
        .await?
        .parameter
        .and_then(|p| p.value)
        .unwrap_or_default();

    println!("{}", value);

    Ok(())
}

Profile IconIkuma Yamashita

Rust が好きです。仕事ではインフラエンジニア、趣味ではアプリケーションエンジニアです。イラストなどを嗜む。