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
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.