CodeBuildでの適切な環境変数の取り扱い方について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。

この記事では、CodeBuild プロジェクト環境変数にはクリアテキスト認証情報が含まれている件について、そのリスクと対策を解説します。

ポリシーの説明

[CodeBuild.2] CodeBuild プロジェクト環境変数にクリアテキストの認証情報を含めることはできません

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/codebuild-controls.html#codebuild-2

このコントロールは、プロジェクトに環境変数 AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY が含まれているかどうかをチェックします。

と書かれているため、AWSの認証情報周りを直の環境変数として使ってはダメよという当然の内容です。

認証情報 AWS_ACCESS_KEY_ID および AWS_SECRET_ACCESS_KEY はクリアテキストで保存しないでください。これは、意図しないデータ漏えいや不正アクセスに認証情報が公開される可能性があるためです。

と公式のドキュメントで書かれている通り、クリアテキストで保存せず別の方法を推奨されています。

その他必要となる秘匿情報などはAWS Secrets ManagerやAWS Systems Manager Parameter Storeなどの安全な方法を利用して認証情報を管理するという方式になるかなと思いますので、それを踏まえて以下にまとめます。

修復方法

修正方法についてはIAM Roleを活用したアクセスに変更することとします。

以下にコンソールでのアクセスとTerraformでのサンプルコードをまとめます。

AWSコンソールでの修正手順

  1. Secret Manager > シークレット > 「新しいシークレットを保存する」でシークレットを作成する
  2. 「キー/値」にセットした上で、それぞれ「AWS_ACCESS_KEY_ID」と「AWS_SECRET_ACCESS_KEY 」を入力し次を選択。
  1. シークレット名を入力後、次を入力し、変更内容確認後保存する。
  2. AWS CodeBuild > 対象のCodeBuildのプロジェクトを開き、「編集」をクリックします。

5. 環境のセクションまで下にスクロールし、環境のトグルリストを開きます。 環境変数でAWS_ACCESS_KEY_IDと AWS_SECRET_ACCESS_KEY がプレーンテキストとして保存されている場合は、「タイプ」を「パラメータ」もしくは「Secrets Manager」に変更し、プレーンテキスト以外で取得するようにします。

  1. 「プロジェクトを更新する」をクリックし、設定を保存する。
  2. Secrets Manager 、復号化のためのKMSにアクセスできる適切なIAMロールをCodeBuildにアタッチする

Terraformでの修復手順

このTerraformコードは、CodeBuildプロジェクトの環境変数を直接定義していません。これは、AWS認証情報(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY)を環境変数に含めるべきではないというベストプラクティスに沿ったものです。代わりに、IAMロールを使用してCodeBuildプロジェクトにAWSリソースへのアクセス許可を付与し、認証情報を環境変数としてハードコードすることを避けます。

# 現在のAWSアカウントIDを取得
data "aws_caller_identity" "current" {}

# 現在のAWSリージョンを取得
data "aws_region" "current" {}

# CodeBuildプロジェクトの設定
resource "aws_codebuild_project" "example" {
  name         = "example-project"
  service_role = aws_iam_role.codebuild_role.arn

  //認証情報を入れないことがポイント
  environment {
    compute_type                = "BUILD_GENERAL1_SMALL"
    image                       = "aws/codebuild/amazonlinux2-x86_64-standard:3.0"
    type                        = "LINUX_CONTAINER"
    image_pull_credentials_type = "CODEBUILD"
  }

  source {
    type            = "GITHUB"
    location        = "<https://github.com/example/repo.git>"
    git_clone_depth = 1
  }

  artifacts {
    type = "NO_ARTIFACTS"
  }
}

# IAMロールの設定
resource "aws_iam_role" "codebuild_role" {
  name = "codebuild-example-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "codebuild.amazonaws.com"
        }
      }
    ]
  })
}

# CodeBuild基本ポリシー
resource "aws_iam_role_policy" "codebuild_base_policy" {
  role = aws_iam_role.codebuild_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Resource = [
          "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/codebuild/${aws_codebuild_project.example.name}",
          "arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:log-group:/aws/codebuild/${aws_codebuild_project.example.name}:*"
        ]
        Action = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
      },
      {
        Effect = "Allow"
        Resource = [
          "arn:aws:s3:::codepipeline-${data.aws_region.current.name}-*"
        ]
        Action = [
          "s3:PutObject",
          "s3:GetObject",
          "s3:GetObjectVersion",
          "s3:GetBucketAcl",
          "s3:GetBucketLocation"
        ]
      }
    ]
  })
}

# プロジェクト固有のポリシー(例:S3バケットアクセス)
resource "aws_iam_role_policy" "project_specific_policy" {
  role = aws_iam_role.codebuild_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Resource = [
          "arn:aws:s3:::example-bucket",
          "arn:aws:s3:::example-bucket/*"
        ]
        Action = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:ListBucket"
        ]
      }
    ]
  })
}

このTerraformコードで重要なポイントは service_role = aws_iam_role.codebuild_role.arn のところで、IAMロールにて必要なアクセス許可設定を行うことでAWS認証情報を設定する必要なく、各AWSリソースへのアクセスを可能としているポイントです。 従って、本ポリシーを遵守する場合はIAMロールに必要なアクセス許可ポリシーを設定した上で、CodeBuildのサービスロールに適用し使用しなければなりません。

最後に

今回は、CodeBuild プロジェクトの環境変数にクリアテキストの認証情報を含めることのリスクとその対策についてご紹介しました。環境変数に機密情報を含めると、意図しないデータ漏えいや不正アクセスのリスクが高まります。設定を確認し、該当する場合は本記事を参考に修正してみてください。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る