Claude Code × AWS S3: sync, imagens, backups e URLs pré-assinadas com menor privilégio
Guia Claude Code e AWS S3: IAM menor privilégio, aws s3 sync, site estático, imagens, backups e URLs pré-assinadas.
S3 parece apenas um lugar para guardar arquivos, mas em uma aplicação real aparecem permissões, exposição pública, sync, cache, exclusão e custo. Claude Code acelera scripts e helpers, mas um prompt vago pode gerar uma policy ampla demais.
Este guia é para quem quer usar S3 perto de produção com segurança. Vamos cobrir site estático, upload de imagens, backups e URLs pré-assinadas. A regra central é least privilege: cada script recebe apenas a action e o prefix necessários.
Os comandos seguem a documentação oficial: AWS CLI S3 reference, aws s3 sync reference, Boto3 presigned URL guide, Claude Code common workflows.
Para contexto adicional, veja também: IAM, security, context.
Separar os usos do S3 antes do código
use case 1 é site estático. dist vai para site/ e CloudFront entrega. use case 2 é imagem. O admin envia para uploads/ ou assets/images/. use case 3 é backup. Dumps e PDFs usam prefixo de data e não usam —delete. use case 4 é download privado com URL curta pré-assinada.
Se tudo fica misturado, s3:* parece tentador. Defina prefixos como site/, assets/images/, uploads/, backups/ e assets/private-reports/. Com essas fronteiras, Claude Code gera algo mais fácil de revisar.
Identidade e IAM com menor privilégio
Coloque bucket e região em variáveis para que você e o Claude Code revisem o mesmo alvo.
export AWS_REGION=ap-northeast-1
export S3_BUCKET=claudecode-lab-assets-prod
aws sts get-caller-identity
aws s3 ls "s3://${S3_BUCKET}/" --region "${AWS_REGION}"
Essa policy lê apenas assets, grava apenas uploads e evita permissão ampla de exclusão.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadPublicAssetsOnly",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::claudecode-lab-assets-prod/assets/*"
},
{
"Sid": "WriteUploadsOnly",
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:AbortMultipartUpload"],
"Resource": "arn:aws:s3:::claudecode-lab-assets-prod/uploads/*"
},
{
"Sid": "ListLimitedPrefixes",
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::claudecode-lab-assets-prod",
"Condition": {
"StringLike": {
"s3:prefix": ["assets/*", "uploads/*", "backups/*"]
}
}
}
]
}
Esse é o formato básico para sites estáticos ou pastas de imagens. Comece sempre com dryrun.
# 1. Preview changes first. This should become a habit.
aws s3 sync ./dist "s3://${S3_BUCKET}/site/" \
--region "${AWS_REGION}" \
--delete \
--cache-control "public,max-age=300" \
--dryrun
# 2. Deploy only after the preview looks right.
aws s3 sync ./dist "s3://${S3_BUCKET}/site/" \
--region "${AWS_REGION}" \
--delete \
--cache-control "public,max-age=300"
# 3. Upload long-lived images with a different cache policy.
aws s3 sync ./public/images "s3://${S3_BUCKET}/assets/images/" \
--region "${AWS_REGION}" \
--exclude "*.psd" \
--cache-control "public,max-age=31536000,immutable"
Uma URL pré-assinada mantém o bucket privado e libera download por pouco tempo.
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({ region: process.env.AWS_REGION ?? "ap-northeast-1" });
export async function createDownloadUrl(key: string, filename: string) {
if (!key.startsWith("assets/private-reports/")) {
throw new Error(`Unexpected S3 key prefix: ${key}`);
}
const command = new GetObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
ResponseContentDisposition: `attachment; filename="${filename}"`,
});
return getSignedUrl(s3, command, { expiresIn: 900 });
}
Ao pedir ao Claude Code, inclua objetivo, proibições e comandos de verificação.
このリポジトリに AWS S3 連携を追加してください。
目的: public/images を S3 の assets/images/ に同期し、private-reports/ のPDFだけ署名付きURLで配布する。
制約: バケット全体公開は禁止。s3:DeleteObject は付けない。aws s3 sync は必ず --dryrun を先に出す。
成果物: scripts/s3-sync-assets.mjs、lib/s3-presigned-url.ts、READMEの手順、確認コマンド。
確認: npm test、aws s3 ls、aws s3 sync --dryrun の出力で説明してください。
参照: AWS CLI s3/sync docs と Anthropic Claude Code common workflows。
A policy é estreita de propósito: GetObject só em assets, PutObject só em uploads e ListBucket limitado por prefix. Erros comuns são ListBucket em ARN de objeto e s3:* no bucket inteiro.
DeleteObject é outro pitfall. Muitos fluxos não precisam dele. Se for necessário, separe role ou script, com dryrun, contagem de deletes e confirmação humana. Claude Code escreve JSON; o escopo final é revisão humana.
Usar aws s3 sync com segurança
aws s3 sync compara caminho local e prefix S3. Com —delete, remove do remoto o que não existe localmente. Ótimo para deploy estático determinístico, perigoso para backups e pastas compartilhadas.
# Backup use case: append-only, no --delete.
BACKUP_DATE=$(date +%Y-%m-%d)
aws s3 sync ./backups "s3://${S3_BUCKET}/backups/${BACKUP_DATE}/" \
--region "${AWS_REGION}" \
--storage-class STANDARD_IA \
--exclude "*.tmp"
aws s3 ls "s3://${S3_BUCKET}/backups/${BACKUP_DATE}/" --recursive --summarize
Meu padrão é dryrun primeiro. O script deve mostrar bucket, região, prefix e diff. Se houver muitos deletes, ele para. Esse cuidado simples evita o pior caso: pasta errada com —delete.
URL pré-assinada é permissão temporária
Uma presigned URL permite uma ação S3 por tempo limitado. O bucket continua privado. Serve para PDFs, relatórios, exports e downloads por usuário após autenticação.
Três detalhes importam: expiresIn é em segundos, o prefix do key deve ser validado e o nome vindo do navegador não deve virar key final. Gere keys no servidor, como uploads/yyyy/mm/dd/uuid.ext. URL longa demais em produção é failure comum.
Custos, cache e exposição pública
Custo de S3 não é só armazenamento. Requests, transferência, CloudFront, versioning e lifecycle também contam. Assets públicos devem usar CloudFront e cache-control; arquivos privados não devem exigir bucket público.
DRYRUN_OUTPUT=$(aws s3 sync ./dist "s3://${S3_BUCKET}/site/" --delete --dryrun)
echo "$DRYRUN_OUTPUT"
DELETE_COUNT=$(echo "$DRYRUN_OUTPUT" | grep -c "delete:" || true)
if [ "$DELETE_COUNT" -gt 20 ]; then
echo "Too many deletes: ${DELETE_COUNT}. Stop and review."
exit 1
fi
Tutoriais antigos usam S3 static website hosting com bucket público. Hoje, private S3 + CloudFront costuma ser mais seguro e mais fácil de explicar em auditorias.
O que delegar ao Claude Code e o que revisar
Claude Code é bom para scripts de sync, helpers TypeScript, README, testes e mensagens de erro. A revisão humana olha conta AWS, bucket, prefix, DeleteObject, public access e CloudFront. Antes de executar, use aws sts get-caller-identity e aws s3 ls.
Nota de verificação do Masa: separar prefixos foi o maior ganho. Com site, assets, uploads, backups e private-reports, a revisão IAM e os prompts ficaram claros. Pedir verification steps junto com o código também aumentou a confiança.
Resumo
Claude Code × AWS S3 funciona muito bem quando as permissões continuam chatas. Separe use cases, use dryrun, evite DeleteObject amplo, mantenha S3 privado e gere URLs pré-assinadas curtas.
Para adaptar isso a um repositório real, use training / consultation.
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
Claude Code Free PDF Funnel Checklist: transformar tráfego em cadastros e cliques de produto
Checklist para levar leitores ao PDF grátis, produtos Gumroad e consultoria com Claude Code.
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.