GitHub Actions が OpenID Connect をサポートし、デプロイがよりセキュアに出来るようになりました!

記事タイトルとURLをコピーする

はじめに

アプリケーションサービス部の宮本です。 今回は先日一般公開となった GitHub Actions の OpenID Connect サポートについてご紹介します。GitHub Actions から AWS リソースの操作を行なっている方にとっては必見のアップデートです。

github.blog

何が変わったのか

これまで、GitHub Actions から AWS リソースの作成などを行う場合、IAM ユーザーを作成し、認証情報(アクセスキー、シークレットキー)を生成、GitHub Actions の Secrets に設定する必要がありました。

この方法は気軽に利用できる一方、認証情報のローテーションなど漏洩に対するリスク管理が必要で、積極的に利用したい方法ではありませんでした。

今回、GitHub Actions が OpenID Connect をサポートしたことにより、永続的な認証情報を預けることなく、OpenID Connect の仕様に則った一時的なトークン発行のみで、AWS リソースの操作が出来る様になりました。

f:id:swx-miyamoto:20211102221425p:plain
概要イメージ (公式ブログ より引用)

図内の Cloud Provider が AWS に相当します。予め OpenID プロバイダと信頼関係を設定した IAM ロールを用意することで、認証情報不要で当該ロールに AssumeRole することが出来ます。

やってみる

AWS 提供の Action にちょうど良いサンプル があったのでこれをベースに S3 バケットへのファイルアップロードを試します。(S3 バケット、GitHub リポジトリは作成済みの前提で進めます。)

1. IAM ロールの作成、OpenID プロバイダーの登録

IAMロールの作成、OpenID プロバイダーの登録 を以下 CFn テンプレートで行います。ほぼサンプルからの転用ですが、S3 へのファイルアップロードの為にマネージドポリシー AmazonS3FullAccess を追加しています。(実運用では最小のアクセス権限を付与するようにしてください。)

パラメータは以下の3つです。

パラメータ名 説明
GitHubOrg Action を実行する GitHub リポジトリが所属する GitHub Organization (ユーザー名)を指定します。
RepositoryName Action を実行する GitHub リポジトリ名を指定します。
OIDCProviderArn GitHub を OpenID プロバイダーとして既に登録済みの場合は、その ARN を指定します。指定しなければ新規作成されます。
# example-github-actions-oidc.yaml
Parameters:
  GitHubOrg:
    Type: String
  RepositoryName:
    Type: String
  OIDCProviderArn:
    Description: Arn for the GitHub OIDC Provider.
    Default: ""
    Type: String

Conditions:
  CreateOIDCProvider: !Equals 
    - !Ref OIDCProviderArn
    - ""

Resources:
  Role:
    Type: AWS::IAM::Role
    Properties:
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonS3FullAccess
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !If 
                - CreateOIDCProvider
                - !Ref GithubOidc
                - !Ref OIDCProviderArn
            Condition:
              StringLike:
                token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${RepositoryName}:*

  GithubOidc:
    Type: AWS::IAM::OIDCProvider
    Condition: CreateOIDCProvider
    Properties:
      Url: https://token.actions.githubusercontent.com
      ClientIdList: 
        - sts.amazonaws.com
      ThumbprintList:
        - a031c46782e6e6c662c2c87c76da9aa62ccabd8e

Outputs:
  Role:
    Value: !GetAtt Role.Arn 

GithubOidc の各プロパティは環境に合わせて変更する必要はなく、上記例のままで問題ありません。スタック作成後、作成されたロールの ARN を控えておきましょう。

2. GitHub Actions のワークフロー作成、各種設定

こちらも公式ドキュメントのサンプルを転用し、リポジトリ直下の .github/workflows/ に任意の名前でワークフローファイルを作成します。リポジトリへの Push トリガーでワークフローが実行され、S3 バケットにファイルがアップロードされる仕組みです。

BUCKET_NAMEAWS_REGIONROLE_ARN (前述の手順で作成した IAM ロールの ARN) は予め GitHub の Secrets に設定しておく必要があります。

# .github/workflows/example.yaml

# Sample workflow to access AWS resources when workflow is tied to branch
# The workflow Creates static website using aws s3
name: AWS example workflow
on:
  push
env:
  BUCKET_NAME : ${{secrets.BUCKET_NAME}}
  AWS_REGION : ${{secrets.AWS_REGION}}
# permission can be added at job level or workflow level    
permissions:
  id-token: write
  contents: write    # This is required for actions/checkout@v1
jobs:
  S3PackageUpload:
    runs-on: ubuntu-latest
    steps:
      - name: Git clone the repository
        uses: actions/checkout@v1
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@master
        with:
          role-to-assume: ${{secrets.ROLE_ARN}}
          role-session-name: samplerolesession
          aws-region: ${{env.AWS_REGION}}
      # Upload a file to AWS s3
      - name:  Copy index.html to s3
        run: |
          aws s3 cp ./index.html s3://${{env.BUCKET_NAME}}/

3. 動作確認

これで準備は概ね完了です。S3 へアップロードする index.html を任意の内容で作成し、ファイル一式を Commit、GitHub へ Push しましょう。

実行の結果、ログは GitHub リポジトリの Actions タブから確認できます。

f:id:swx-miyamoto:20211102234413p:plain
実行結果

index.html がアップロードされているかも確認します。バケット名はご自身の環境に書き換えてください。

$ aws s3 ls s3://<your-bucket-name>
2021-11-02 23:42:46          0 index.html

まとめ

認証情報(アクセスキー、シークレットキー)を発行せずに、GitHub Actions から AWS リソースの操作を行うことが出来ました。比較的簡単な手順で実現できますので積極的に導入していきましょう。

参考