Use Cases

Claude Code × AWS IAM 完全ガイド|最小権限ポリシーを自動生成・レビューする

AWS IAMポリシーの設計をClaude Codeで効率化。最小権限の原則に基づくポリシー自動生成・既存ポリシーのセキュリティレビュー・CDK実装まで実例コードで解説。

IAMポリシーの設計は「地味だけど間違えると致命的」な作業です。ワイルドカード (*) を乱用した過剰権限ポリシーは、セキュリティインシデントの温床になります。かといって一から最小権限ポリシーを書くのは時間がかかる。

私は業務でLambda・S3・DynamoDB・CloudWatchを組み合わせたサーバーレスアーキテクチャを運用していますが、IAMポリシーの設計・レビューを Claude Code に任せることで、作業時間を約70%削減しました。この記事では、その実践的な手順を解説します。


IAMの基本を3分で復習

ポリシーの構造

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "StringEquals": {
          "s3:prefix": ["uploads/"]
        }
      }
    }
  ]
}
  • Effect: Allow (許可) または Deny (拒否)
  • Action: 許可/拒否するAPIアクション
  • Resource: 対象リソースのARN (具体的に指定するほど安全)
  • Condition: 追加条件 (IPアドレス制限・MFA必須など)

最小権限の原則

「必要な操作だけを、必要なリソースだけに許可する」が IAMの鉄則です。

❌ 危険: ワイルドカード乱用
Action: "*"
Resource: "*"

✅ 安全: 具体的に指定
Action: ["s3:GetObject", "s3:PutObject"]
Resource: "arn:aws:s3:::my-uploads-bucket/user-files/*"

Step 1: 用途を伝えてポリシーを自動生成

Lambda用ポリシーの生成

claude -p "
以下の Lambda 関数に必要な最小権限 IAM ポリシーを JSON で生成して。

【Lambda の処理内容】
- S3 バケット 'user-uploads-prod' から画像を読み取り
- 加工後に 'user-thumbnails-prod' に保存
- 処理結果を DynamoDB テーブル 'image-metadata' に記録
- エラー時は SNS トピック 'alert-topic' に通知
- CloudWatch Logs にログ出力

【制約】
- 削除操作は不要
- リソース ARN はアカウントID 123456789012、リージョン ap-northeast-1 を使用
- Condition でソース IP を社内 IP (203.0.113.0/24) に制限しない (Lambdaは不要)
"

生成例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ReadSourceBucket",
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": "arn:aws:s3:::user-uploads-prod/*"
    },
    {
      "Sid": "S3WriteThumbnailBucket",
      "Effect": "Allow",
      "Action": ["s3:PutObject"],
      "Resource": "arn:aws:s3:::user-thumbnails-prod/*"
    },
    {
      "Sid": "DynamoDBWriteMetadata",
      "Effect": "Allow",
      "Action": ["dynamodb:PutItem", "dynamodb:UpdateItem"],
      "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/image-metadata"
    },
    {
      "Sid": "SNSPublishAlert",
      "Effect": "Allow",
      "Action": ["sns:Publish"],
      "Resource": "arn:aws:sns:ap-northeast-1:123456789012:alert-topic"
    },
    {
      "Sid": "CloudWatchLogs",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/lambda/*"
    }
  ]
}

Step 2: 既存ポリシーのセキュリティレビュー

既存のポリシーに問題がないかレビューしてもらいます。

claude -p "
以下の IAM ポリシーをセキュリティの観点でレビューして。
問題点と修正案を具体的に教えて。

$(cat policy.json)
"

Claude Code が指摘してくれる典型的な問題:

問題1: Resource: "*" でS3へのフルアクセスを許可している
  → 対象バケットとプレフィックスを具体的に指定すること

問題2: s3:DeleteObject が含まれているが処理上不要
  → 削除操作を除去すること

問題3: iam:PassRole を wildcard resourceで許可している
  → PassRole は特定のロールARNにのみ許可すること (特権昇格リスク)

問題4: CloudTrail の有効化確認が取れていない
  → IAM操作のログ記録を有効にすることを推奨

Step 3: ロール設計の自動化

複数サービスにまたがるロール設計

claude -p "
以下のアーキテクチャで必要な IAM ロールを全て設計して:

【アーキテクチャ】
- API Gateway → Lambda (認証)
- Lambda → DynamoDB (ユーザーデータ読み書き)
- Lambda → S3 (ファイル保存)
- Lambda → SES (メール送信)
- CloudWatch Events → Lambda (バッチ処理)
- CodePipeline → S3, CodeBuild, Lambda (デプロイ)

【出力形式】
- 各ロールの名前と用途
- 信頼ポリシー (Trust Policy)
- アクセスポリシー
- AWS CDK の TypeScript コードで出力
"

CDKでのロール実装

// lib/iam-stack.ts
import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import * as lambda from "aws-cdk-lib/aws-lambda";

export class IamStack extends cdk.Stack {
  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Lambda実行ロール (最小権限)
    const lambdaRole = new iam.Role(this, "ApiLambdaRole", {
      assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
      roleName: "api-lambda-role",
      description: "API Lambda用の最小権限ロール",
    });

    // DynamoDB読み書き権限 (特定テーブルのみ)
    lambdaRole.addToPolicy(
      new iam.PolicyStatement({
        sid: "DynamoDBAccess",
        effect: iam.Effect.ALLOW,
        actions: [
          "dynamodb:GetItem",
          "dynamodb:PutItem",
          "dynamodb:UpdateItem",
          "dynamodb:Query",
        ],
        resources: [
          `arn:aws:dynamodb:${this.region}:${this.account}:table/users`,
          `arn:aws:dynamodb:${this.region}:${this.account}:table/users/index/*`,
        ],
      })
    );

    // S3書き込み権限 (特定バケット・プレフィックスのみ)
    lambdaRole.addToPolicy(
      new iam.PolicyStatement({
        sid: "S3FileUpload",
        effect: iam.Effect.ALLOW,
        actions: ["s3:PutObject", "s3:GetObject"],
        resources: [
          `arn:aws:s3:::user-files-${this.account}/uploads/*`,
        ],
      })
    );

    // SESメール送信権限
    lambdaRole.addToPolicy(
      new iam.PolicyStatement({
        sid: "SESSendEmail",
        effect: iam.Effect.ALLOW,
        actions: ["ses:SendEmail", "ses:SendRawEmail"],
        resources: ["*"],
        conditions: {
          StringEquals: {
            "ses:FromAddress": "[email protected]",
          },
        },
      })
    );

    // CloudWatch Logsへの書き込み権限
    lambdaRole.addManagedPolicy(
      iam.ManagedPolicy.fromAwsManagedPolicyName(
        "service-role/AWSLambdaBasicExecutionRole"
      )
    );
  }
}

Step 4: IAM Access Analyzerの結果をレビュー

AWS IAM Access Analyzerの出力をClaude Codeにレビューしてもらいます。

# Access Analyzerの結果を取得
aws accessanalyzer list-findings --analyzer-arn arn:aws:access-analyzer:... \
  --output json > analyzer-findings.json

claude -p "
以下の IAM Access Analyzer の検出結果を読んで:
1. 重大度別 (HIGH/MEDIUM/LOW) に分類
2. 即座に修正が必要なものを特定
3. それぞれの修正方法を具体的に教えて

$(cat analyzer-findings.json)
"

Step 5: SCPの設計 (組織全体のガードレール)

AWS Organizationsを使っている場合は、SCP (Service Control Policy) でアカウント全体のガードレールを設けます。

claude -p "
本番環境のAWSアカウントに適用する SCP を設計して。
以下の要件を満たすこと:

1. ap-northeast-1 (東京) と us-east-1 (バージニア) 以外のリージョンを無効化
2. root アカウントによるAPI操作を禁止
3. CloudTrail の無効化・削除を禁止
4. GuardDuty の無効化を禁止
5. 特定のIAMロール ('OrganizationAdminRole') への変更を禁止
"
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyUnsupportedRegions",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": ["ap-northeast-1", "us-east-1"]
        },
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/OrganizationAdminRole"
          ]
        }
      }
    },
    {
      "Sid": "DenyCloudTrailModification",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:StopLogging",
        "cloudtrail:UpdateTrail"
      ],
      "Resource": "*"
    }
  ]
}

落とし穴4選

1. iam:PassRole の過剰権限

// ❌ 危険: どのロールでも渡せる
{
  "Action": "iam:PassRole",
  "Resource": "*"
}

// ✅ 安全: 特定ロールのみ
{
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::123456789:role/MyLambdaRole",
  "Condition": {
    "StringEquals": {
      "iam:PassedToService": "lambda.amazonaws.com"
    }
  }
}

2. 管理ポリシーの乱用

AmazonS3FullAccess などの AWS 管理ポリシーは便利ですが、必要以上の権限を含みます。Lambda が S3 から読むだけなら s3:GetObject のみのカスタムポリシーを使いましょう。

3. インラインポリシーとカスタム管理ポリシーの混在

インラインポリシーは再利用できず、追跡が困難です。管理ポリシーに統一してバージョン管理しましょう。

4. 条件 (Condition) なしの MFA 必須化が漏れる

管理者ロールへのスイッチには必ず MFA を必須にします。

{
  "Condition": {
    "BoolIfExists": {
      "aws:MultiFactorAuthPresent": "true"
    }
  }
}

まとめ

タスクClaude Code の貢献
ポリシー生成用途を説明するだけで最小権限ポリシーを生成
セキュリティレビュー既存ポリシーの問題点と修正案を指摘
ロール設計アーキテクチャ全体のロール構成を設計
CDK実装TypeScriptのIAMコードを自動生成
SCP設計組織全体のガードレールポリシーを生成

IAMは「作って終わり」ではなく、定期的なレビューが必要です。月1回、Claude Code に既存ポリシーをレビューさせる習慣をつけるだけで、セキュリティリスクを継続的に低減できます。

関連記事

参考資料

#claude-code #aws #iam #security #typescript #infrastructure

Claude Codeをもっと活用しませんか?

実務で使えるプロンプトテンプレート50選。コピペですぐ使えます。

無料プレゼント

無料PDF: Claude Code 5分でわかるチートシート

メールアドレスを登録するだけで、A4 1枚のチートシートPDFを今すぐお送りします。

個人情報は厳重に管理し、スパムは送りません。

Masa

この記事を書いた人

Masa

現役DX室長|Claude Code でゼロから多言語AI技術メディア運営中。実務直結の自動化、AI開発相談・研修受付中。

PR

関連書籍・参考図書

この記事のテーマに関連する書籍を楽天ブックスで探せます。

※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。