CodeBuildプロジェクトのアーティファクトでのCMKの適用について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
今回は、AWS CodeBuildプロジェクトのアーティファクトがAWS管理キーで暗号化されており、カスタマー管理キー (CMK) 以上のレベルで暗号化されていない状態について、そのリスクと対策を解説します。

リスク
AWS CodeBuildは、ソースコードをコンパイルし、単体テストを実行し、デプロイ可能なアーティファクトを作成するフルマネージド型のビルドサービスです。CodeBuildは、ビルドの過程で生成されるキャッシュ、ログ、テストレポート、そして最終的なビルド結果などのアーティファクトをS3バケットに保存しますが、これらのアーティファクトはデフォルトでAWS管理キー(AWS managed key)によって暗号化されます。要求されるコンプライアンスの基準に応じてKMSカスタマー管理キー(CMK)を利用した暗号化を適用するようにしましょう。
修復方法
AWS CodeBuildプロジェクトのアーティファクトをKMSカスタマー管理キー(CMK)で暗号化する方法は、AWSコンソールまたはTerraformで行えます。
AWSコンソールでの修復手順
AWSコンソールを使用して、AWS CodeBuildプロジェクトのアーティファクトの暗号化にKMS CMKを設定します。
前提:
- アーティファクトを暗号化するためのAWS KMS カスタマー管理キー (CMK) が既に存在すること。
- CMKのキーポリシーには、CodeBuildのサービスロールがキーを使用するための適切な権限(
kms:Encrypt
,kms:Decrypt
など)が付与されている必要があります。
- CMKのキーポリシーには、CodeBuildのサービスロールがキーを使用するための適切な権限(
- CodeBuildプロジェクトがアーティファクトをS3に出力するように設定されていること。
- CodeBuildサービスへ移動: AWSコンソールにログインし、AWS CodeBuild サービスを開きます。
- ビルドプロジェクトを選択: 左側のナビゲーションペインで「ビルド」の下にある「ビルドプロジェクト」を選択します。 OACを設定したいCloudFrontディストリビューションを選択します。
- プロジェクトの編集: CMKで暗号化したいビルドプロジェクトを選択し、「編集」をクリックします。
- アーティファクト設定へ移動: 「編集」ドロップダウンから「アーティファクト」を選択します。
- アーティファクトの暗号化設定: 「プライマリ出力アーティファクト」セクション(または追加のアーティファクトセクション)を見つけます。
- 「暗号化」のドロップダウンメニューで、「AWS Key Management Service カスタマー管理キー (CMK) を選択する」を選択します。
- 表示されるドロップダウンリストから、使用したい既存のKMS CMKを選択します。
- もし適切なCMKがリストに表示されない場合は、正しいIAM権限があるか、またはCMKが作成されているか確認してください。

- 環境変数の設定(オプション): ビルドプロセス中に環境変数としてKMSキーIDを渡す必要がある場合は、「環境」セクションで設定できます。
- 変更を適用: 「ビルド設定を更新」をクリックして、変更を保存します。
これで、今後このCodeBuildプロジェクトによって生成されるビルドアーティファクトは、指定したKMS CMKを使用してS3に保管される際に暗号化されるようになります。
Terraformでの修復手順
TerraformでAWS CodeBuildプロジェクトのアーティファクト暗号化をKMSカスタマー管理キー(CMK)で有効にするには、aws_codebuild_project
リソースの artifacts
ブロックにある encryption_key
パラメータを設定します。
# (例) CodeBuildアーティファクト暗号化用のKMSカスタマー管理キー (CMK)
resource "aws_kms_key" "codebuild_artifacts_cmk" {
description = "KMS key for CodeBuild artifacts encryption"
deletion_window_in_days = 10 # キーの削除をスケジュールするまでの日数
enable_key_rotation = true # キーの自動ローテーションを有効にする
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Sid = "Enable IAM User Permissions",
Effect = "Allow",
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" # アカウントルートユーザーにアクセス許可
},
Action = "kms:*",
Resource = "*"
},
{
Sid = "Allow CodeBuild Service Role to use the key"
Effect = "Allow",
Principal = {
AWS = aws_iam_role.codebuild_role.arn # CodeBuildのサービスロールARNを指定
},
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
Resource = "*"
}
]
})
tags = {
Name = "CodeBuildArtifactsCMK"
}
}
# CodeBuildがS3バケットにビルドアーティファクトを保存するためのS3バケット
resource "aws_s3_bucket" "codebuild_artifacts_bucket" {
bucket = "my-codebuild-artifacts-bucket-unique-20250706" # グローバルで一意の名前に変更
acl = "private"
tags = {
Name = "CodeBuildArtifacts"
}
}
# CodeBuildサービスロール
resource "aws_iam_role" "codebuild_role" {
name = "codebuild-service-role"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "codebuild.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
# CodeBuildサービスロールにアタッチするポリシー
resource "aws_iam_role_policy" "codebuild_policy" {
name = "codebuild-policy"
role = aws_iam_role.codebuild_role.id
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
Resource = "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/codebuild/${aws_codebuild_project.my_project.name}:*"
},
{
Effect = "Allow",
Action = [
"s3:PutObject",
"s3:GetObject",
"s3:GetObjectVersion",
"s3:GetBucketAcl",
"s3:GetBucketLocation"
],
Resource = [
"${aws_s3_bucket.codebuild_artifacts_bucket.arn}/*",
aws_s3_bucket.codebuild_artifacts_bucket.arn
]
},
{
Effect = "Allow",
Action = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
Resource = aws_kms_key.codebuild_artifacts_cmk.arn
}
]
})
}
# CodeBuildプロジェクト
resource "aws_codebuild_project" "my_project" {
name = "my-secure-codebuild-project"
service_role = aws_iam_role.codebuild_role.arn
build_timeout = "5" # minutes
artifacts {
type = "S3"
location = aws_s3_bucket.codebuild_artifacts_bucket.id
path = "/"
packaging = "NONE" # または ZIP
# KMS CMKを指定してアーティファクトを暗号化
encryption_key = aws_kms_key.codebuild_artifacts_cmk.arn
}
source {
type = "CODEPIPELINE" # または GITHUB, S3, BITBUCKETなど
buildspec = "buildspec.yml"
}
environment {
compute_type = "BUILD_GENERAL1_SMALL"
image = "aws/codebuild/standard:5.0"
type = "LINUX_CONTAINER"
privileged_mode = false
image_pull_credentials_type = "CODEBUILD"
}
tags = {
Environment = "Production"
}
}
上記のTerraformコードでは、aws_codebuild_project
リソース内の artifacts
ブロックで encryption_key
パラメータを設定することで、CodeBuildプロジェクトのアーティファクトをKMS CMKで暗号化しています。
aws_kms_key.codebuild_artifacts_cmk
: CodeBuildのアーティファクト暗号化に使用するKMSカスタマー管理キー (CMK) を作成します。このキーのポリシーには、CodeBuildサービスロールがキーを使用するための適切な権限が必要です。aws_codebuild_project.my_project.artifacts.encryption_key
: ここに作成したKMS CMKのARNを指定します。aws_iam_role.codebuild_role
とaws_iam_role_policy.codebuild_policy
: CodeBuildサービスがS3バケットへのアクセスとKMSキーの使用を許可するために必要なIAMロールとポリシーを定義します。ポリシーには、S3へのアクセス権限と、KMS CMKに対する暗号化/復号化権限が含まれていることを確認してください。
my-codebuild-artifacts-bucket-unique-20250706
や my-secure-codebuild-project
などのプレースホルダーは、実際の環境に合わせて修正してください。
最後に
この記事では、AWS CodeBuildプロジェクトのビルドアーティファクトをKMSカスタマー管理キー(CMK)以上で暗号化することの重要性について解説しました。この設定は、CI/CDパイプライン全体のセキュリティを強化し、機密データの保護、コンプライアンス要件の遵守、そしてサプライチェーン全体の信頼性を確保するために不可欠です。 貴社のCodeBuildプロジェクトのアーティファクトは、カスタマー管理キー以上のレベルで暗号化されていますか?この機会にぜひ設定を確認・強化してみてください。 こちらの内容の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。運用が非常にラクに出来る製品になっていますのでぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。