Use Cases (Diperbarui: 1/6/2026)

Claude Code × AWS S3: sync, unggah gambar, backup, dan URL bertanda tangan dengan izin minimum

Panduan Claude Code dan AWS S3: IAM least privilege, aws s3 sync, situs statis, upload, backup, presigned URL.

Claude Code × AWS S3: sync, unggah gambar, backup, dan URL bertanda tangan dengan izin minimum

S3 terlihat seperti tempat menyimpan file, tetapi di aplikasi nyata Anda harus memikirkan permission, public access, sync, cache, delete, dan biaya. Claude Code bisa membuat script dan helper dengan cepat, tetapi prompt yang terlalu umum bisa menghasilkan IAM policy yang terlalu luas.

Panduan ini untuk pemula yang ingin memakai S3 secara aman. Kita membahas static site, upload gambar, backup, dan presigned URL. Prinsipnya adalah least privilege: setiap script hanya mendapat action dan prefix yang benar-benar dibutuhkan.

Contoh mengikuti dokumentasi resmi: AWS CLI S3 reference, aws s3 sync reference, Boto3 presigned URL guide, Claude Code common workflows.

Untuk konteks tambahan, lihat juga: IAM, security, context.

Pisahkan use case S3 sebelum menulis kode

use case 1 adalah static site. dist disinkronkan ke site/ lalu disajikan CloudFront. use case 2 adalah gambar. Admin upload ke uploads/ atau assets/images/. use case 3 adalah backup. Dump dan PDF memakai prefix tanggal dan tidak memakai —delete. use case 4 adalah download privat dengan presigned URL singkat.

Jika semua dicampur, s3:* terlihat mudah. Lebih baik buat prefix seperti site/, assets/images/, uploads/, backups/, dan assets/private-reports/. Dengan batas ini, output Claude Code lebih mudah direview.

Identitas dan IAM least privilege

Simpan bucket dan region sebagai variabel agar Anda dan Claude Code memeriksa target yang sama.

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}"

Policy ini hanya membaca assets, hanya menulis uploads, dan menghindari izin hapus yang luas.

{
  "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/*"]
        }
      }
    }
  ]
}

Ini bentuk dasar untuk situs statis atau folder gambar. Selalu mulai dengan 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"

Presigned URL menjaga bucket tetap private tetapi memberi akses download sementara.

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 });
}

Saat meminta Claude Code, sertakan tujuan, larangan, dan perintah verifikasi.

このリポジトリに 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。

Policy ini sengaja sempit: GetObject hanya assets, PutObject hanya uploads, dan ListBucket dibatasi prefix. Kesalahan umum adalah menaruh ListBucket pada object ARN atau memberi s3:* ke seluruh bucket.

DeleteObject adalah pitfall lain. Banyak alur tidak perlu delete. Jika perlu, pisahkan role atau script dengan dryrun, jumlah delete, dan konfirmasi manual. Claude Code boleh menulis JSON, tetapi manusia tetap meninjau scope.

Gunakan aws s3 sync dengan aman

aws s3 sync membandingkan folder lokal dan prefix S3. Dengan —delete, file remote yang tidak ada lokal akan dihapus. Bagus untuk deploy static site, berbahaya untuk backup dan folder media bersama.

# 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

Pola saya: dryrun dulu. Script harus menampilkan bucket, region, prefix, dan diff. Jika delete terlalu banyak, script berhenti. Ini sederhana tetapi mencegah folder salah plus —delete.

Presigned URL adalah izin sementara

Presigned URL memberi akses S3 dalam waktu terbatas tanpa membuat bucket public. Cocok untuk PDF privat, invoice, export report, atau download per pengguna setelah login.

Perhatikan tiga hal: expiresIn memakai detik, prefix key harus divalidasi, dan nama file dari browser jangan langsung menjadi S3 key. Buat key di server seperti uploads/yyyy/mm/dd/uuid.ext. URL terlalu lama adalah failure yang umum.

Biaya, cache, dan public access

Biaya S3 bukan hanya storage. Request, transfer data, CloudFront, versioning, dan lifecycle juga berpengaruh. Asset public sebaiknya lewat CloudFront dengan cache-control; file privat jangan memakai bucket public.

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

Tutorial lama sering memakai S3 static website hosting dengan bucket public. Untuk produksi modern, private S3 + CloudFront biasanya lebih aman dan mudah dijelaskan saat audit.

Bagian Claude Code dan bagian review manusia

Claude Code cocok untuk script sync, helper TypeScript, README, test, dan pesan error. Manusia mengecek AWS account, bucket, prefix, DeleteObject, public access, dan CloudFront. Sebelum menjalankan, pakai aws sts get-caller-identity dan aws s3 ls.

Catatan verifikasi Masa: pemisahan prefix memberi dampak terbesar. Setelah site, assets, uploads, backups, dan private-reports dipisah, review IAM dan prompt Claude Code menjadi jelas. Meminta verification steps bersama kode juga membuat operasi lebih dipercaya.

Ringkasan

Claude Code × AWS S3 sangat berguna jika permission tetap sederhana. Pisahkan use case, pakai dryrun, hindari DeleteObject luas, jaga S3 private, dan gunakan presigned URL singkat.

Untuk menerapkan pola ini pada repositori nyata, gunakan training / consultation.

#claude-code #aws #s3 #iam #aws-cli #security
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.