前回の記事で、AWSを利用したGitHub ActionsによるCI構築に向け、S3とCloudFrontの環境構築を行いました。
今回の記事では、Actions構築時に利用するAWSの認証情報について、直接IDやキーの値をGitHubに連携する方法ではなく、よりセキュアな手法であるOIDC(OpenID Connect)を利用したActions構築のための手順について紹介します。
GitHub Actionsによるワークフロー構築において、外部クラウドサービスを利用する場合には、それらのサービスの認証情報を指定する必要があります。
一般的に、その認証情報はGitHubの環境変数(Secrets)として登録され、ワークフローの中の処理で参照されます。
こうした従来のワークフロー構築に置き換わるベストな選択肢が、OIDCを利用したワークフロー構築です。
従来の手法では、環境変数とは言え認証情報をハードコーディングする等のリスクがありました。しかしOIDCを利用することで、
と言った恩恵が得られるため、従来よりもセキュアで柔軟な選択肢と言えます。
詳細についてはこちらで解説されています。
ここでは、実際にAWSでOIDCを作成する手順を紹介します(rootアカウントでの操作です)。
①IAM > IDプロバイダ > IDプロバイダを作成
②下記の情報を参考に、プロバイダを追加
IDプロバイダのためのロールを作成する前に、ロールが実行可能な権限ポリシーを独自に作成します。
①IAM > ポリシー > ポリシーの作成
②ステップ1:ポリシーエディタを「JSON」とし、下記を参考にポリシーを編集
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::S3バケット名"
},
{
"Sid": "Statement2",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::S3バケット名/*"
},
{
"Sid": "Statement3",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "arn:aws:cloudfront::AWSアカウントID:distribution/ディストリビューション名"
}
]
}
③ステップ2:任意のポリシー名を入力し、ポリシーを作成
JSONポリシーの内容について補足します。
Resourceオプションで指定するS3バケットの参照を可能にする権限です。
Resourceオプションで指定するS3バケット配下のオブジェクトの参照・更新を可能にする権限です。
Resourceオプションで指定するCloudfrontディストリビューションに対し、キャッシュ削除を可能にする権限です。
最後に、IDプロバイダとポリシーを関連付けるためのロールを作成します。
後にGitHub Actions内のジョブで利用するロールです。
①IAM > IDプロバイダ> 対象プロバイダを選択 > ロールの割り当て > 新しいロールを作成
②ステップ1:下記を参考に、エンティティを設定
GitHub組織:GitHub Actionsを実行するリポジトリを保有する組織またはユーザー名
GitHubリポジトリ:GitHub Actionsを実行するリポジトリ
GitHubブランチ:"main" ※任意ですが、不特定多数のブランチを許可する必要が無ければ入力を推奨します。
③ステップ2:前項で作成したポリシーを選択
④ステップ3:任意のロール名を入力し、ロールを作成
以上で、OIDCを利用したロールの作成は完了です。
「信頼されたエンティティ」について補足します。
ロール一覧 > 対象ロール選択 > 信頼関係 より、信頼ポリシーのJSONが確認できます。
Condition
オプション内容に若干差があるかもしれませんが、おそらくこんなJSONが登録されているはずです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AWSアカウントID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": [
"sts.amazonaws.com"
],
"token.actions.githubusercontent.com:sub": [
"repo:GitHub組織またはユーザー名/リポジトリ名:ref:refs/heads/main"
]
}
}
}
]
}
ざっくり日本語訳すると、
「このOIDCプロバイダを利用して認証され、且つ条件を満たしたエンティティだけがロールを継承できるよー」
というものです。
継承後に実行可能な権限については前項で補足しましたね。
ここでは、「条件」に該当するCondition
オプションについてもう少し補足します。
先ず、上記のJSONにおける条件内容を解説すると、
「OIDCが発行するトークンがsts.amazonaws.comをターゲットとしており、且つ発行されたトークンは指定したユーザーが保有するリポジトリのmainブランチ産のものである」
というものです。
なお、StringEquals
は条件が完全一致であることを保証するオプションです。
かなり厳密な条件であることが分かります。
仮に、もう少し緩やかな条件を許容できる場合には、Condition
配下を下記のようなJSONとすることも可能です。
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub": [
"repo:GitHub組織またはユーザー名/リポジトリ名:*"
]
}
}
これは、不特定多数のブランチによるトークンでも許可する、という条件です。
環境にも依りますが、ベターとは言えないでしょう。
また、sts.amazonaws.comをターゲットとする条件も取り除いています。そもそもこの条件はIDプロバイダの設定時に保証されている内容なので、JSON上必須ではありませんが、明示する方が望ましいです。
往々にして、本番環境をmainブランチ、開発検証をdevelopブランチとして使い分けている運用方法も多いのではないでしょうか。
複数且つ特定のブランチのみを許可する場合には、
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": [
"sts.amazonaws.com"
],
"token.actions.githubusercontent.com:sub": [
"repo:GitHub組織またはユーザー名/リポジトリ名:ref:refs/heads/main",
"repo:GitHub組織またはユーザー名/リポジトリ名:ref:refs/heads/develop"
]
}
}
このように、環境に合わせて柔軟に条件を設定することで、より最適なロールに近づけることができます。
ポリシー内で設定可能な条件について、詳細はこちらから確認できます。
第2回の本記事では、AWSサービスへアクセスするGitHub Actionsの構築において、OIDCを利用した従来よりもベストな選択肢を取るための、AWS上での設定手順について紹介しました。
AWS上での設定はこれで完了したので、次回はNuxt3の環境構築について紹介します。