Use Cases (Atualizado: 03/06/2026)

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.

Claude Code e AWS IAM: guia prático de políticas de menor privilégio

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:

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 usoPrincipalPermissões necessáriasEvitar explicitamente
Lambda de miniaturasRole de execução LambdaLer um prefixo S3, escrever um prefixo S3, escrever uma tabela DynamoDB, publicar um tópico SNS, escrever logsApagar S3, ler todos os buckets, ações IAM
Upload no painel administrativoRole Lambda de APIPutObject em um prefixo S3, GetItem em uma tabela DynamoDBList no bucket inteiro, gestão de chaves KMS
Deploy pelo GitHub ActionsRole CI com OIDCAtualizar um stack CloudFormation e a Lambda alvoAdministratorAccess, ações em todas as regiões
Investigação de incidenteUsuário federadoBuscar CloudWatch Logs, ler X-Ray, GetItem na tabela relevanteAtualizar, 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.

#claude-code #aws #iam #security #typescript #infrastructure
Grátis

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.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.