OpenID ConnectによるID連携をして、Lambdaにデプロイする

# やること
- OpenID ConnectによるID連携をして、Github ActionsでAWSのresourceにアクセスするのを試す

成果物を作るがてら、OpenID Connect周りの理解を深めればと思います。

# OpenID Connectとは
- OpenID Connect 1.0 は、RFC6749のOAuth2.0を拡張した簡単な識別レイヤー
- OpenIDはIDトークンを発行する仕組み
- IDトークンを発行する際の登場人物は、クライアント、OpenIDプロバイダー、ユーザの3つで、
  - ①クライアント→OpenIDプロバイダーにトークン発行のリクエスト
  - ②OpenIDプロバイダーはユーザから認証を得る
  - ③OpenIDプロバイダー→クライアントにIDトークンとアクセストークン返す
  - ④クライアントはアクセストークンでユーザ情報のエンドポイントにリクエストする
  - ⑤クライアントはユーザ情報のレスポンスを受け取る
- 上記でIDプロバイダーで発行したIDトークンを引き回すことで、別の場所でユーザ認証を繰り返す必要がなく、これを「ID連携」と呼ぶそうです。

今回はこのOpenID ConnectのID連携を使って、Github ActionsでAWSの認証を行います。

# ID連携をするためのAWS側の設定をする
やることは2つ
①identity providerを用意する
②ROLEを割り当てる

[AWSのドキュメント](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html#manage-oidc-provider-console)に載っている通りに進めます。

まず、identity providerを用意します。
IAMのページにアクセスして、Identity providers→add provider→OpenID Conenctを選択します。
Provider URLとAudienceは、[Github側のドキュメント](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)に書いてあるOICD Providerの設定を入れます。

```
For the "Audience": Use sts.amazonaws.com if you are using the official action.
```
とあり、今回はaws-actions/configure-aws-credentialsを使うため、入れます。
作ると、下記のようにできます。

![スクリーンショット 2022-08-13 16.28.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/bd95c339-dad3-8601-030a-b9b80fc98963.png)

次にこのIdentity providerで認証するroleを割り当てます。
今回はgithub actions用のroleを作るため、「Create a new role」を選択します。
policyについては、後ほど必要なものを入れます。一旦、適当な名前でroleを作ります。

![スクリーンショット 2022-08-13 16.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/497c9094-5a26-9214-8a99-3561f6ece254.png)

次に、このroleにs3にアップロードするためのpolicyも設定します。
今回は、インラインポリシーを作ります。
visual editorで必要な権限とリソースを確認して、追加します。
今回は、s3にファイルを上げるだけなため、下記のような設定になります。

##### s3にファイルをアップロードするポリシー
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::${your bucket name}/*"
        }
    ]
}
```

設定したら、roleに付与します。
![スクリーンショット 2022-08-13 20.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/aa52a90f-1078-2bac-9037-3ea53147239c.png)

最後に、このroleにTrust RelationShipを設定します。
手動で、subject conditionを追加します。

##### trusted entities
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:${GithubOrg}/${RepositoryName}:*"
                }
            }
        }
    ]
}
```

これで、AWS側の設定は一旦終わりです。

# Github Actionsの設定をする
やることは1つ
①workflowでassumeするroleを指定する

こちらも[Githubのドキュメント](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services)を参考に進めます。

設定といっても、上記に書いたようにworkflowsを用意して、AWSで設定したroleを、assumeするroleとして指定するだけです。
今回は、s3にファイルをアップロードして動作を確かめます。

```yaml
name: s3-upload
on:
  push
env:
  BUCKET_NAME : "${your bucket name}"
  AWS_REGION : "${your region name}"
permissions:
  id-token: write
  contents: read
jobs:
  S3PackageUpload:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: 
        with:
          role-to-assume: arn:aws:iam::674767932536:role/github-actions-test
          role-session-name: github-actions-test
          aws-region: ${{ env.AWS_REGION }}
      - run: |
          aws s3 cp ./index.html s3://${{ env.BUCKET_NAME }}
```

[サンプル](https://github.com/KouheiHara/GithubActionsTest)

上記のworkflowは、pushがトリガーになっているので、pushすると発火します。
GithubのActionsタブを開くと、workflowの実行が確認できます。
![スクリーンショット 2022-08-13 21.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275351/5b96f5b8-3fd9-6228-dd7d-41e55aba29b5.png)

あとは指定のバケットにファイルがアップロードされていることを確認します。
確認できたら、OpenID ConnectによるID連携をして、s3にファイルアップロードができたことになります。

# 参考

Creating OpenID Connect(OIDC) identity providers
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html#manage-oidc-provider-console

一番分かりやすいOpenID Connectの説明
https://qiita.com/TakahikoKawasaki/items/498ca08bbfcc341691fe

Configuring OpenID Connect in Amazon Web Services
https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

Creating OpenID Connect (OIDC) identity providers
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html#manage-oidc-provider-console