アクセスキーを使ってGitHub ActionsからAWSへアクセスするのはもうやめよう! 

## これは何?

GitHub ActionsからAWSのリソースへのアクセスする際にはなんらかの認証情報が必要です。

一昔前は，GitHub Actions Secretsに保存したAWSのアクセスキーとシークレットを埋め込む形が一般的でした。
しかし，最近この方法は非推奨になっています。

本記事では，Open ID Connectの技術を利用することによってよりセキュアにGitHub Actionsを使用する方法について紹介します。

---

## OpenID Connectとは

https://www.openid.or.jp/document/ より抜粋

> OpenID Connect 1.0 は, OAuth 2.0 プロトコルの上にシンプルなアイデンティティレイヤーを付与したものである. このプロトコルは Client が Authorization Server の認証結果に基づいて End-User のアイデンティティを検証可能にする. また同時に End-User の必要最低限のプロフィール情報を, 相互運用可能かつ RESTful な形で取得することも可能にする.
> この仕様は, OpenID Connect の主要な機能である OAuth 2.0 上で End-User の情報伝達のためにクレームを用いる認証機能を定義する. この仕様はまた, OpenID Connect を利用するための Security, Privacy Considerations を説明する.

平たく言うと，OpenID提供サイトに登録したID情報を使って、ほかのOpenID対応サイトにログインすることを可能にするプロトコルであり，OAuth 2.0をベースにしたプロトコルです。
これにより，サイトごとにバラバラで管理していた認証情報を一元管理することができるのがメリットになります。

詳しく勉強したい方は以下の本がおすすめです。

https://booth.pm/ja/items/1296585

https://booth.pm/ja/items/1550861

https://www.shoeisha.co.jp/book/detail/9784798159294

---

## アクセスキーを使う方法とOpenID Connectを使う方法を比較する

- GitHub ActionsでAWSに認証する古いやり方

```yaml
      - name: Configure AWS credentials
        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 }}
          aws-region: ${{ env.AWS_DEFAULT_REGION }}

```
- OpenID Connectを使う方式では，以下のように，AWSのアカウントID(数字)とIAM Role名を指定する

```yaml
    # 本記事で紹介する方法
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ env.AWS_DEFAULT_REGION }}
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_DEPLOY_ROLE }}
          role-session-name: myGitHubActions

```

アクセスキーを使う方法とは異なり，毎回一時的なアクセスキーがAWSのID Providerから払い出されることになるので万が一アクセスキーのローテーションなどの手間が省けます

---

## GitHub ActionsからAWSへのリソースへのアクセスをやってみる

基本的には[GitHubの公式ドキュメント(https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)をベースに自分が詰まった部分や作業時のスクリーンショット等を補足して書いていきます。

### AWSにID Providerを作成する

IAMのページから**Identity proviers**のページに行き，作成します。今回は[公式のActoins](https://github.com/aws-actions/configure-aws-credentials)を使って認証を行うため，公式ドキュメントどおりに設定を行います。

> - プロバイダURLには https://token.actions.githubusercontent.com を指定します
> - 「対象者」には sts.amazonaws.com を指定します。(公式のアクションを利用する場合)。

![Screenshot from 2025-01-14 16-26-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/d581c02b-75c3-b488-c130-57df3bd4a496.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/b417082c-8382-1f22-f6fb-18456d797bad.png)

---

## IAM Roleを作成する

GitHub Actionsから認証後に使用できる権限を制御するためのIAM Roleを作成します。
セキュリティの最小限速に従い，なるべく必要な権限のみを付与するようにしましょう。
このあたりはAWS-CLIやTerraformで作業した方が楽な気もしますが，一旦GUIでの手順を書いておきます。

1. Web Identityを選択して作成
    ![Screenshot from 2025-01-14 17-12-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/c15e47ad-ab93-5b58-5bd3-c6e87fe3f9e1.png)
    - Providerとして`token.actions.githubusercontent.com`を指定します。
    - Organizationsには所属するGitHub Organizationsを指定します。
    :::note info
    個人リポジトリの場合にはGitHubのユーザ名を指定する
    - Repositoryやブランチを絞りたい場合にはそれらも設定する
2. 付与したいPolicyを作成もしくは指定してIAM Roleを作成します。

---

### GitHub Actions Secretを設定

- AWSのアカウントID

    :::note info
    アカウントIDはログイン時に指定するユーザIDではなく，AWS自体のアカウントID(数字12桁)である
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/4b8cbd3f-c24f-7815-c2df-94930d25eb58.png)

- 上の手順で作成したIAM Role名

をGitHub Actions Secretsに登録します。
登録はリポジトリの設定ページから可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3718390/0b0b885d-80ce-77e7-1268-6664e9b5f04c.png)

:::note info
今回は検証のため，適当な変数名で作成しましたが，複数のリポジトリやRole名を使うことが想定されるため，わかりやすい名前をつけたほうが良いと思います。
:::


### GitHub Actionsのyamlを作成する

リポジトリルート/.github/workflows/配下に.yamlファイルを作成します。
検証用なのでGitHubにpush時にとりあえず，動くようにしました。
`${{ secrets.hoge }}`のようにしてsecretsは使用でき，これはGitHub Actionsのログに表示する際にも伏せ字になります。

```yaml
name: deploy to s3 using oidc
on:
  push:

defaults:
  run:
    shell: bash

env:
  AWS_DEFAULT_REGION: us-east-1
  AWS_DEFAULT_OUTPUT: json

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write # oidc用

    steps:
      - uses: actions/checkout@v4
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ env.AWS_DEFAULT_REGION }}
          role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/${{ secrets.AWS_DEPLOY_ROLE }}
          role-session-name: myGitHubActions
      - run: |
          aws sts get-caller-identity # 検証用のコマンド

```

git push時にAWSに認証が成功したことで，AWS-CLIのコマンドが問題なく実行できることが確認できました。

---

## 感想など

- そこそこ時間がかかるかなと思っていたが，OIDCの知識等がなくても容易に設定できそうに感じた。
- 使用した公式のactionsの中身を読んだらOIDCの知識が深まりそう