🔍

Terraform BackendでPoLPを実現: log 分析による必要最小限の権限適用

に公開

TL;DR

Terraform で AWS の Backend(S3 + DynamoDB)を構成する際、つい AmazonS3FullAccess のような managed policy を付与してしまいがちです。しかし、これは PoLP(最小権限の原則) に反します。実際に必要な権限だけを特定し、正確に付与することがセキュリティ上適切です。

この記事では、Terraform applyの log を分析して呼び出されたAPIを抽出し、それに基づいて精緻化されたIAM Policyを構成した過程を共有します。

Terraformの Debug log からAPI使用状況を抽出する

まず、 Debug log を有効にして、Terraform apply実行時にどのAWS APIが呼び出されるかを記録します。

export TF_LOG=DEBUG
export TF_LOG_PATH=./terraform.log
terraform apply

その後、log から S3 および DynamoDB に関連する AWS API呼び出し情報を抽出しました。

cat terraform.log | grep -E 'rpc.service=(S3|DynamoDB)' | awk '{
  for(i=1; i<=NF; i++) {
    if($i ~ /^rpc.service=/) service = $i;
    if($i ~ /^rpc.method=/) method = $i;
  }
  if(service && method) print service ":" method;
}' | sed -E 's/rpc.service=([^:]*):rpc.method=([^:]*)$/\1:\2/' | sort | uniq -c

   2 DynamoDB:CreateTable
   2 DynamoDB:DescribeContinuousBackups
  12 DynamoDB:DescribeTable
   2 DynamoDB:DescribeTimeToLive
   1 DynamoDB:GetBucketTagging
   2 DynamoDB:ListTagsOfResource
   1 DynamoDB:PutBucketLifecycleConfiguration
   2 S3:CreateBucket
   2 S3:GetBucketAccelerateConfiguration
   2 S3:GetBucketAcl
   3 S3:GetBucketCors
   2 S3:GetBucketEncryption
  32 S3:GetBucketLifecycleConfiguration
   2 S3:GetBucketLogging
   3 S3:GetBucketPolicy
   3 S3:GetBucketReplication
   2 S3:GetBucketRequestPayment
   4 S3:GetBucketTagging
   2 S3:GetBucketVersioning
   3 S3:GetBucketWebsite
   3 S3:GetObjectLockConfiguration
   6 S3:HeadBucket
   1 S3:PutBucketLifecycleConfiguration

出力された結果には、実際には存在しない Action(e.g. DynamoDB:GetBucketTagging など)が含まれていたり、 log に表示されたメソッド名と IAM Policy の Action 名が一致しないものがありました。これらの部分は GPT の助けを借りて、実際に必要な Action に正確に整理しました。

実際に必要なIAMPolicy一覧(精緻化後)

以下は、最終的に構成した PoLP に基づくIAMPolicyです。実際に呼び出される Action のみを含め、リソースも具体的に指定しています。

{
  "Version": "2012-10-17",
  "Statement": [
    {
    "Effect": "Allow",
    "Action": [
      "s3:CreateBucket",
      "s3:ListBucket",
      "s3:GetBucketLocation",
      "s3:GetBucketAcl",
      "s3:GetBucketVersioning",
      "s3:GetBucketPolicy",
      "s3:GetBucketRequestPayment",
      "s3:GetBucketLogging",
      "s3:GetEncryptionConfiguration",
      "s3:GetLifecycleConfiguration",
      "s3:GetBucketObjectLockConfiguration",
      "s3:PutLifecycleConfiguration",
      "s3:GetBucketTagging",
      "s3:GetReplicationConfiguration",
      "s3:GetAccelerateConfiguration",
      "s3:GetBucketCORS",
      "s3:GetBucketWebsite"
    ],
    "Resource": [
      "arn:aws:s3:::<BUCKET_NAME>",
      "arn:aws:s3:::<BUCKET_NAME>/*"
    ]
    },
    {
    "Effect": "Allow",
    "Action": [
      "dynamodb:CreateTable",
      "dynamodb:DescribeTable",
      "dynamodb:DescribeContinuousBackups",
      "dynamodb:DescribeTimeToLive",
      "dynamodb:ListTagsOfResource"
    ],
    "Resource": "arn:aws:dynamodb:ap-northeast-1:XXX:table/<TABLE_NAME>"
    },
    {
    "Effect": "Allow",
    "Action": "sts:GetCallerIdentity",
    "Resource": "*"
    }
  ]
}

まとめ

この記事では、Terraform の Debug log を分析して、実際に必要な AWS API 呼び出しを特定し、それに基づいて精緻化された IAM Policy を構成しました。この方法は、AWS の API 使用状況を正確に把握し、最小限の権限を適用するための有効な手段です。

  • Terraform の Debug log を分析することで、実際に呼び出される AWS API 情報を抽出できます。
  • これを IAM Policy(Action)にマッピングすることで、正確で最小限の Policy を構成できます。
  • 「よくわからないから FullAccess」のような過剰なPolicyは避け、「実際に必要な権限」のみを正確に設定することが望ましいです。
  • まず log を確認することで、PoLP(最小権限の原則)を適用するのがはるかに容易になります。

Discussion