AWS S3
s3cmd
S3 permissions
file synchronization
cloud storage management

Necessary s3cmd S3 permissions for PUT/Sync

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

The exact S3 permissions that s3cmd put or s3cmd sync need depend on how you use the command. A simple upload needs fewer actions than a bidirectional sync with ACL changes and deletion. The safest way to reason about it is to map each command behavior to the S3 API actions it triggers.

Minimum Permissions for Uploading

For a straightforward upload into a known bucket path, the essential object-level permission is usually s3:PutObject.

A minimal upload example is:

bash
s3cmd put report.csv s3://my-bucket/uploads/report.csv

A minimal IAM policy for that case looks like this:

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Action": ["s3:PutObject"],
7      "Resource": ["arn:aws:s3:::my-bucket/uploads/*"]
8    }
9  ]
10}

That is enough only for the simplest case where the tool can upload the object directly and does not need to inspect bucket contents.

sync Usually Needs More Than PutObject

s3cmd sync compares local and remote state, so it normally needs bucket listing permissions in addition to upload permission.

bash
s3cmd sync ./site/ s3://my-bucket/site/

A more realistic policy often includes:

  • 's3:ListBucket to enumerate objects in the bucket or prefix'
  • 's3:PutObject to upload changed files'
  • 's3:GetObject in some workflows where metadata inspection or comparisons matter'

Example:

json
1{
2  "Version": "2012-10-17",
3  "Statement": [
4    {
5      "Effect": "Allow",
6      "Action": ["s3:ListBucket"],
7      "Resource": ["arn:aws:s3:::my-bucket"]
8    },
9    {
10      "Effect": "Allow",
11      "Action": ["s3:PutObject", "s3:GetObject"],
12      "Resource": ["arn:aws:s3:::my-bucket/site/*"]
13    }
14  ]
15}

If sync is only pushing local files and comparing against S3 state, this is often close to the practical minimum.

Add Delete Permission Only If You Use Deletion

If you run sync with deletion behavior, such as removing remote objects that no longer exist locally, you also need s3:DeleteObject.

bash
s3cmd sync --delete-removed ./site/ s3://my-bucket/site/

Then the policy must include:

json
"s3:DeleteObject"

This is an important separation because many teams want upload-only synchronization and do not want the same credential to delete production objects.

ACL and Metadata Options Need Extra Actions

If you use s3cmd flags that set ACLs, you may also need s3:PutObjectAcl.

For example, older static-site workflows often include public-read ACL changes. Without s3:PutObjectAcl, the upload may succeed while the ACL step fails.

Similarly, some operations may need:

  • 's3:GetBucketLocation'
  • object tagging permissions if tagging is used
  • encryption-related permissions if the bucket enforces KMS usage

That is why the exact command flags matter when defining the IAM policy.

Keep the Scope Narrow

A good production policy does not grant access to every bucket. Limit both bucket-level and object-level resources to the exact prefix being synchronized.

For example:

  • bucket resource for listing: arn:aws:s3:::my-bucket
  • object resource for writes: arn:aws:s3:::my-bucket/site/*

This preserves least privilege while still allowing s3cmd to do its job.

A Practical Debugging Sequence

If s3cmd fails, ask:

  1. is this a plain put or a sync
  2. does the command compare existing bucket contents
  3. does it delete remote objects
  4. does it set ACLs or metadata that need extra permissions

Once you answer those, the IAM action list becomes much easier to derive.

Common Pitfalls

  • Granting only s3:PutObject and expecting sync to work often fails because sync usually needs s3:ListBucket too.
  • Forgetting s3:DeleteObject when using deletion flags causes partial sync behavior that looks inconsistent.
  • Using ACL-related s3cmd options without s3:PutObjectAcl leads to confusing permission errors after the upload step.
  • Scoping s3:ListBucket to an object ARN instead of the bucket ARN breaks listing because bucket-level and object-level resources are different in IAM.
  • Overbroad wildcard permissions are easy to write but weaken least-privilege security unnecessarily.

Summary

  • 's3:PutObject is the basic permission for uploads.'
  • 's3cmd sync usually also needs s3:ListBucket, and sometimes s3:GetObject.'
  • Add s3:DeleteObject only if the sync command removes remote files.
  • Add s3:PutObjectAcl if your workflow sets ACLs.
  • Build the policy from the exact command behavior instead of guessing a one-size-fits-all permission set.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.