0
1

IAMロールとGitHub Actionsの統合によるデプロイのセキュリティ強化

Last updated at Posted at 2023-11-03

これまで、AWS SDKをLambdaにデプロイする際のクレデンシャル(IAMユーザーのアクセスキーとシークレットアクセスキー)管理について課題を感じていました。

環境変数からリソースの強い操作権限をもったIAMユーザーのアクセスキーを読み込む方法だと、キーが流出したときのセキュリティリスクが大きいので、IAMロールを利用する方法に変更しました。

本記事では、この変更を実施する際の手順を備忘録としてまとめています。

手順

GitHub ActionsのデプロイワークフローでGitHub SecretsからAssumeRole権限をもったIAMユーザーのアクセスキーとシークレットアクセスキーを読み込み、AssumeRoleでIAMロールの権限を引き受けるようにしました。

IAMユーザーの作成

コンソールやIaCツールからIAMユーザーを作成し、以下のカスタムポリシーを作成して関連付けます。
Resource欄については、IAMロール作成後にARNをコピペします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ],
            "Resource": "arn:aws:iam::<Account ID>:role/<Role Name>"
        }
    ]
}

追記
sts:AssumeRoleだけじゃなく、sts:TagSessionも必須です。

次に、「セキュリティ認証情報 > アクセスキー」からアクセスキー(およびシークレットアクセスキー)を発行します。

このアクセスキーは、GitHub ActionsのデプロイワークフローでAssumeRole(IAMロールの権限を引き受ける)際に必要となります。

注意
このIAMユーザーはリソースの操作権限を持っていません。
もしキーが第三者に漏れても、重大なリソース操作は行えないため、セキュリティのリスクは低いですが、それでも流出を防ぐための対策(キーのローテーションなど)が必要です。

追記 2024-01-07
OpenID Connectを使用すれば、IAMユーザーの作成は不要です。

OpenID Connectを使用してGitHub Actionsでアクセスキーレスなデプロイをおこなう

IAMロールの作成

IAMユーザーと同様に、コンソールやIaCからIAMロールを作成します。

デプロイワークフロー用のIAMロール

こちらのポリシーには、デプロイに必要なリソースの操作権限(CloudFormation, API Gateway, Lambda, ECR, IAMなど)を付与します。

次に、IAMロールの「信頼関係」タブに移動し、「信頼されたポリシー」の編集を選択します。信頼ポリシーでは、どのエンティティがロールを引き受けることができるかを定義します。

PrincipalAWSには、先ほど作成したIAMユーザーのARNをコピペします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<Account ID>:user/<User Name>"
            },
            "Action": [
                "sts:AssumeRole",
                "sts:TagSession"
            ],
            "Condition": {}
        }
    ]
}

Lambda用のIAMロール

こちらのポリシーには、アプリケーションで必要なリソースの操作権限(S3, SESなど)を付与します。

Lambda詳細画面の「設定タブ > アクセス権限」から、実行ロールとして作成したIAMロールを関連付けます。
これでアプリケーションのコード上でクレデンシャルを読み込む必要がなくなります。
スクリーンショット 2023-11-03 9.10.49.png

GitHub Secretsへの環境変数の登録

GitHubリポジトリのSettingsタブから「Secrets and variables > Actions」を選択し、「New repository secret」からワークフローで使用する環境変数(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_IAM_ROLE_TO_ASSUME)を登録します。

AWS_IAM_ROLE_TO_ASSUMEにはIAMロールのARNを入力します。

スクリーンショット 2023-11-03 8.58.14.png

GitHub Actionsデプロイワークフローの修正

以下がデプロイワークフローの一部です。
configure awsのステップで先ほど設定した環境変数を読み込んでいます。

name: Lambda Deploy
on:
  push:
    branches:
      - develop
    paths:
      - "**"
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: install dependencies
        run: yarn install
        working-directory: ./

      - name: configure aws
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_TO_ASSUME }}
          role-duration-seconds: 3600

注意
role-duration-seconds: 3600の秒数はIAMロールの最大セッション時間以下に設定する必要があります。

ローカル環境での開発

Lambdaデプロイ後の環境ではLambdaの実行ロールでAWSリソースの操作が可能になりますが、ローカル環境(Dockerなど)では実行ロールがないため、従来通りクレデンシャルを環境変数から読み込む運用となります。

そのため、アプリケーションのコードを以下のように修正する必要があります。

  private createS3Client(): S3Client {
    const options: S3ClientConfig = {
      region: 'ap-northeast-1',
      ...(process.env.ENV === 'local' && {
        credentials: {
          accessKeyId: process.env.ACCESS_KEY_ID as string,
          secretAccessKey: process.env.SECRET_ACCESS_KEY as string
        }
      })
    }

    return new S3Client(options)
  }

おわりに

ECSにデプロイする場合も大体同じような手順です。
ECSタスク定義でタスクロールを指定することにより、ECSタスクが実行されるEC2インスタンスやFargate上で動作するコンテナがAWSリソースにアクセスできるようになります。
このタスクロールは、特定のAWSサービスやリソースに対するアクセス権限を定義するIAMポリシーをアタッチすることでカスタマイズ可能です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1