Claude Code × AWS IAM指南:安全设计最小权限策略
用Claude Code设计AWS IAM最小权限,并用Access Analyzer和CDK验证落地。
AWS IAM决定“谁可以对哪个AWS资源做什么”。策略只是一个JSON文件,但随手写下Action: "*"或Resource: "*",就可能让Lambda、CI任务或人工账号拥有远超需要的权限。Claude Code很适合生成初稿和做审查,但不能把它当成自动批准器。
本文介绍一个可复制的流程:先写清楚使用场景,让Claude Code生成草稿,再用IAM Access Analyzer验证,用人审查ARN和业务边界,最后用CDK固化,并测试“应该成功”和“应该失败”的操作。初学者可以这样理解:策略是权限规则,角色是工作负载临时扮演的身份,主体是正在使用权限的人或服务。
Masa在实际项目中踩过坑:为了热修复,给生产Lambda临时加了过宽的S3权限,结果几周后才在审查中发现。没有造成泄露,但它说明了一件事:Claude Code可以节省起草时间,不能替代责任。
以AWS官方文档为基准
本文的IAM建议基于以下AWS官方资料:
- Security best practices in IAM
- IAM JSON policy element reference
- Validate policies with IAM Access Analyzer
- Temporary security credentials in IAM
- Permissions boundaries for IAM entities
核心原则很直接:人类用户优先使用联合身份和临时凭证,工作负载使用IAM角色,权限按最小范围授予,用Access Analyzer检查策略,定期删除未使用的用户、角色、权限和凭证。
flowchart LR
A["写清使用场景"] --> B["Claude Code生成草稿"]
B --> C["人工检查ARN"]
C --> D["IAM Access Analyzer验证"]
D --> E["用CDK代码化"]
E --> F["测试允许与拒绝"]
先固定具体使用场景
不要只对Claude Code说“写一个IAM策略”。要说明执行主体、资源、允许操作,以及必须禁止的操作。
| 使用场景 | 主体 | 需要的权限 | 明确避免 |
|---|---|---|---|
| 缩略图生成Lambda | Lambda执行角色 | 读取一个S3前缀、写入一个S3前缀、写入一个DynamoDB表、发布一个SNS主题、写日志 | S3删除、读取所有桶、IAM操作 |
| 管理后台上传辅助 | API用Lambda角色 | 对一个S3前缀执行PutObject、读取一个DynamoDB表 | 整个桶的List、KMS密钥管理 |
| GitHub Actions部署 | OIDC CI角色 | 更新一个CloudFormation栈和目标Lambda | AdministratorAccess、所有区域操作 |
| 故障调查只读角色 | 联合身份用户 | 搜索CloudWatch Logs、查看X-Ray、读取相关表 | 更新、删除、读取Secret |
“明确避免”这一列很重要。生成式工具会自然关注需要什么权限,但如果不写禁止边界,就容易给出偏宽的结果。
可复制的Lambda执行策略
下面的策略用于一个Lambda:从S3读取图片,把缩略图写到另一个S3前缀,把元数据写入DynamoDB,失败时发布SNS通知,并写入CloudWatch Logs。日志组假设由基础设施代码提前创建,因此执行角色不需要logs:CreateLogGroup。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadSourceImages",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::user-uploads-prod/incoming/*"
},
{
"Sid": "WriteThumbnails",
"Effect": "Allow",
"Action": ["s3:PutObject"],
"Resource": "arn:aws:s3:::user-thumbnails-prod/thumbnails/*",
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "AES256"
}
}
},
{
"Sid": "WriteMetadata",
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:UpdateItem"],
"Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/image-metadata"
},
{
"Sid": "PublishAlerts",
"Effect": "Allow",
"Action": ["sns:Publish"],
"Resource": "arn:aws:sns:ap-northeast-1:123456789012:alert-topic"
},
{
"Sid": "WriteLambdaLogs",
"Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/lambda/image-worker-prod:*"
}
]
}
保存为policy-lambda-image-worker.json后执行:
aws accessanalyzer validate-policy \
--policy-document file://policy-lambda-image-worker.json \
--policy-type IDENTITY_POLICY \
--query "findings[?findingType!='SUGGESTION']"
再让Claude Code按固定格式审查:
claude -p "请把policy-lambda-image-worker.json作为AWS IAM最小权限策略审查。
前提:Lambda读取S3 incoming/,写入thumbnails/,写入DynamoDB image-metadata,发布SNS alert-topic,并写CloudWatch Logs。
检查:通配符、删除权限、过宽Resource、Condition是否合理、日志权限范围。
请按Sid / 风险 / 原因 / 更安全的修正输出表格。"
Access Analyzer能检查语法、ARN、动作名、条件键和安全发现,但它不知道业务是否真的需要某个操作。最终判断仍然要由工程师完成。
用CDK固定角色
不要在控制台手工改完就结束。TypeScript CDK可以把角色、日志组和策略放在同一个代码变更审查里确认。下面是lib/image-worker-iam-stack.ts的完整示例。
import * as cdk from "aws-cdk-lib";
import { Stack, StackProps, aws_iam as iam, aws_logs as logs } from "aws-cdk-lib";
import { Construct } from "constructs";
export class ImageWorkerIamStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const account = Stack.of(this).account;
const region = Stack.of(this).region;
new logs.LogGroup(this, "ImageWorkerLogGroup", {
logGroupName: "/aws/lambda/image-worker-prod",
retention: logs.RetentionDays.ONE_MONTH,
removalPolicy: cdk.RemovalPolicy.RETAIN,
});
const role = new iam.Role(this, "ImageWorkerRole", {
assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
description: "Execution role for image-worker-prod Lambda",
});
role.addToPolicy(new iam.PolicyStatement({
sid: "ReadSourceImages",
actions: ["s3:GetObject"],
resources: ["arn:aws:s3:::user-uploads-prod/incoming/*"],
}));
role.addToPolicy(new iam.PolicyStatement({
sid: "WriteThumbnails",
actions: ["s3:PutObject"],
resources: ["arn:aws:s3:::user-thumbnails-prod/thumbnails/*"],
conditions: {
StringEquals: {
"s3:x-amz-server-side-encryption": "AES256",
},
},
}));
role.addToPolicy(new iam.PolicyStatement({
sid: "WriteMetadataAndAlerts",
actions: ["dynamodb:PutItem", "dynamodb:UpdateItem", "sns:Publish"],
resources: [
`arn:aws:dynamodb:${region}:${account}:table/image-metadata`,
`arn:aws:sns:${region}:${account}:alert-topic`,
],
}));
role.addToPolicy(new iam.PolicyStatement({
sid: "WriteLambdaLogs",
actions: ["logs:CreateLogStream", "logs:PutLogEvents"],
resources: [
`arn:aws:logs:${region}:${account}:log-group:/aws/lambda/image-worker-prod:*`,
],
}));
}
}
CI使用OIDC,不保存长期密钥
如果Claude Code参与CI/CD,不要把长期AWS访问密钥放进仓库Secret。GitHub Actions可以通过OIDC扮演IAM角色,获得临时凭证。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:example-org/example-repo:ref:refs/heads/main"
}
}
}
]
}
这是信任策略,决定谁可以扮演角色。权限策略决定扮演之后能做什么。审查时要把这两类文件分开看。
审查时常见的失败点
第一,临时管理员权限没有删除。紧急情况必须放宽时,也要留下负责人、到期日、CloudTrail检查和再次运行Access Analyzer的任务。
第二,S3 ARN写错。s3:ListBucket使用arn:aws:s3:::bucket-name,s3:GetObject和s3:PutObject使用arn:aws:s3:::bucket-name/prefix/*。
第三,给Lambda执行角色随意加IP条件。aws:SourceIp对人工访问或公开API可能有用,但在AWS服务之间调用时经常不符合预期。
第四,只测试成功路径。还要确认DeleteObject、无关桶、无关DynamoDB表和IAM操作会被拒绝。
延伸阅读与下一步
Lambda角色设计可继续看AWS Lambda指南,S3前缀设计看AWS S3入门,日志审计看AWS CloudWatch指南,整体安全检查看Claude Code安全最佳实践。
如果团队想把Claude Code、AWS IAM、CDK和CI权限审查标准化,可以从培训与导入咨询开始。个人学习可以先下载免费速查表,再根据需要查看产品列表中的模板和教材。
我按本文流程实际试了一遍:先写使用场景表,再让Claude Code生成策略,最后用Access Analyzer和拒绝测试检查。效果最明显的是“禁止操作”这一列,提前写出来以后,过宽的S3权限和不必要的日志通配符更容易在部署前被发现。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
从Obsidian到CLAUDE.md的Claude Code流程:不再反复解释上下文
把 Obsidian 工作笔记整理成 CLAUDE.md 运行说明,让 Claude Code 每次都带着正确上下文开始。
Claude Code 收入 CTA 路由:从文章分流到 PDF、Gumroad 与咨询
用 Claude Code 按读者意图把文章流量分到免费 PDF、Gumroad 教材或咨询入口。
Claude Code 团队交接规则: 把审查证据、权限、回滚和收入路径一起交付
面向团队的 Claude Code 交接格式: 证据、权限、回滚、免费 PDF、Gumroad 与咨询路径都要可审查。