Claude Code e AWS IAM: guia prático de políticas de menor privilégio
Projete e valide políticas AWS IAM de menor privilégio com Claude Code, Access Analyzer e CDK.
AWS IAM define quem pode fazer o quê em cada recurso da AWS. Uma política parece apenas um JSON, mas um Action: "*" ou Resource: "*" pode dar a uma Lambda, a um job de CI ou a uma conta humana muito mais acesso do que o necessário. Claude Code ajuda a escrever e revisar políticas, mas não deve virar um aprovador automático de permissões.
O fluxo seguro é simples: descrever o caso de uso, pedir um rascunho ao Claude Code, validar com IAM Access Analyzer, revisar ARN e limites de negócio, implementar com CDK e testar tanto as ações permitidas quanto as negadas. Para iniciantes: política é a regra de permissão, role é a identidade temporária assumida por um workload, e principal é o usuário ou serviço que usa a permissão.
Masa mudou esse processo depois de encontrar uma permissão S3 ampla ainda presa a uma Lambda de produção semanas após um hotfix. Não houve vazamento, mas a conclusão ficou clara: Claude Code reduz o tempo de escrita, não a responsabilidade de revisão.
Use a documentação oficial como base
Esta orientação segue as referências oficiais da 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
Na prática: prefira credenciais temporárias e roles, aplique menor privilégio, valide com Access Analyzer, use condições com cuidado e remova permissões que não são mais usadas.
flowchart LR
A["Escrever o caso de uso"] --> B["Rascunho do Claude Code"]
B --> C["Revisão humana de ARN"]
C --> D["IAM Access Analyzer"]
D --> E["Implementação CDK"]
E --> F["Testes permitidos e negados"]
Comece por casos de uso concretos
Não peça apenas “crie uma política IAM”. Informe ator, recursos, ações permitidas e ações que devem continuar proibidas.
| Caso de uso | Principal | Permissões necessárias | Evitar explicitamente |
|---|---|---|---|
| Lambda de miniaturas | Role de execução Lambda | Ler um prefixo S3, escrever um prefixo S3, escrever uma tabela DynamoDB, publicar um tópico SNS, escrever logs | Apagar S3, ler todos os buckets, ações IAM |
| Upload no painel administrativo | Role Lambda de API | PutObject em um prefixo S3, GetItem em uma tabela DynamoDB | List no bucket inteiro, gestão de chaves KMS |
| Deploy pelo GitHub Actions | Role CI com OIDC | Atualizar um stack CloudFormation e a Lambda alvo | AdministratorAccess, ações em todas as regiões |
| Investigação de incidente | Usuário federado | Buscar CloudWatch Logs, ler X-Ray, GetItem na tabela relevante | Atualizar, apagar, ler secrets |
A coluna de proibições é essencial. Ferramentas generativas tendem a preencher lacunas com permissões amplas quando o limite negativo não está escrito.
Política Lambda pronta para copiar
Esta política é para uma Lambda que lê imagens do S3, grava miniaturas em outro prefixo, escreve metadados no DynamoDB, publica alerta no SNS e grava logs. O grupo de logs é criado antes por infraestrutura como código, então a role não precisa de 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:*"
}
]
}
Salve como policy-lambda-image-worker.json e execute:
aws accessanalyzer validate-policy \
--policy-document file://policy-lambda-image-worker.json \
--policy-type IDENTITY_POLICY \
--query "findings[?findingType!='SUGGESTION']"
Depois peça uma revisão estruturada:
claude -p "Revise policy-lambda-image-worker.json como política AWS IAM de menor privilégio.
Contexto: Lambda lê S3 incoming/, escreve thumbnails/, escreve DynamoDB image-metadata, publica SNS alert-topic e escreve CloudWatch Logs.
Verifique: curingas, permissões de exclusão, Resource amplo demais, Condition correta e escopo de logs.
Retorne uma tabela com Sid, risco, motivo e correção mais segura."
Access Analyzer valida gramática, ARN, nomes de ações, chaves de condição e achados de segurança. Ele não sabe se o produto realmente precisa da permissão. Essa decisão continua sendo humana.
Implemente a role com CDK
Não deixe permissões revisadas apenas no console. Com TypeScript CDK, role, grupo de logs e política ficam na mesma revisão de código.
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 com OIDC, não com chaves longas
Para CI/CD, evite guardar chaves AWS de longo prazo nos secrets do repositório. GitHub Actions pode assumir uma role IAM via OIDC e receber credenciais temporárias.
{
"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"
}
}
}
]
}
Essa é uma política de confiança: decide quem pode assumir a role. A política de permissões decide o que a role pode fazer depois. Revise as duas separadamente.
Falhas comuns
A primeira é deixar acesso administrador temporário para sempre. Se uma emergência exigir permissão ampla, registre responsável, data de expiração, checagem no CloudTrail e nova validação com Access Analyzer.
A segunda é misturar ARN de bucket e objeto S3. s3:ListBucket usa arn:aws:s3:::bucket-name; s3:GetObject e s3:PutObject usam arn:aws:s3:::bucket-name/prefix/*.
A terceira é colocar condição de IP em role Lambda sem entender chamadas entre serviços. aws:SourceIp pode fazer sentido para humanos ou APIs públicas, mas pode quebrar fluxos internos da AWS.
A quarta é testar só o sucesso. Confirme também que s3:DeleteObject, buckets não relacionados, tabelas não relacionadas e ações IAM são negados.
Leituras relacionadas e próximo passo
Para continuar, veja o guia AWS Lambda, o guia AWS S3, o guia AWS CloudWatch e as boas práticas de segurança com Claude Code.
Se sua equipe quer padronizar Claude Code, AWS IAM, CDK e revisão de permissões CI, comece pela página de treinamento e consultoria. Para estudo individual, use a folha gratuita e os modelos da página de produtos.
Testei este fluxo gerando a política com Claude Code, validando o JSON e revisando o CDK contra a mesma tabela de casos de uso. O maior ganho veio de escrever antes as ações proibidas: permissões S3 amplas e curingas de logs desnecessários apareceram antes do deploy.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Workflow Obsidian para CLAUDE.md com Claude Code
Transforme notas de trabalho do Obsidian em notas operacionais CLAUDE.md para preservar contexto.
Claude Code Revenue CTA Routing: artigos para PDF, Gumroad e consultoria
Um fluxo com Claude Code para levar leitores ao PDF grátis, Gumroad ou consultoria conforme intenção.
Regras de handoff para equipes com Claude Code: evidências, permissões, rollback e receita
Formato prático para entregar trabalho do Claude Code com prova, permissões, rollback, PDF grátis, Gumroad e consultoria.