You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何Presigned URL上传S3仍需桶策略?如何配置安全策略?

Why does my S3 presigned URL require a public bucket policy for uploads?

Let’s break this down step by step, since S3’s permission model can feel tricky to navigate at first.

First: Why your presigned URL was failing with AccessDenied

Presigned URLs get their permissions from the IAM entity (user/role) that created them — but S3 doesn’t only check that entity’s permissions. It uses a combined evaluation of four key layers:

  • The IAM permissions of the entity that generated the URL
  • Your bucket policy
  • Object ACLs (if you’re using them)
  • S3 Block Public Access settings

The most likely reason you hit AccessDenied is that your bucket policy was either explicitly denying the s3:PutObject action, or there was no allow statement matching your upload request (S3 defaults to denying access unless explicitly allowed). When you added that open bucket policy, you bypassed those restrictions by granting universal access — but that’s an extremely unsafe fix long-term.

What’s the correct bucket policy for your React app?

You don’t need to make your bucket public. Instead, lock down access to only the entity that generates your presigned URLs (usually your backend server/function that creates URLs for your React frontend).

Step 1: Confirm your presigner IAM entity has the right permissions

First, make sure the IAM user/role that generates the presigned URLs has a policy like this (adjust the resource ARN to match your bucket):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::mybucket/*"
    }
  ]
}

This gives the entity permission to generate URLs that allow uploading to any path in your bucket.

Step 2: Configure a minimal bucket policy (if needed)

In many cases, if your IAM entity has the above permissions and you haven’t set restrictive bucket policies or Block Public Access rules, you might not need a bucket policy at all. But if you have existing bucket policies that deny access, add an allow statement for your presigned URL creator:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPresignedUploads",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_PRESIGNER_ROLE"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::mybucket/*"
    }
    // Add any other necessary statements here (like deny rules for unwanted access)
  ]
}

Replace YOUR_ACCOUNT_ID and YOUR_PRESIGNER_ROLE with the actual ARN of the IAM entity that generates your presigned URLs.

Step 3: Verify Block Public Access settings

Head to your S3 bucket’s permissions tab and double-check these settings:

  • Don’t enable Block all public access (your presigned URLs are private, so this is safe as long as you’re not relying on public ACLs)
  • Enable Block public access to buckets and objects granted through any access control lists (ACLs) to prevent accidental public access via ACLs
  • Enable Block public access to buckets and objects granted through bucket policies (since you don’t need public access here)

Bonus: Frontend upload tips

Make sure your React app’s upload request matches the parameters used to generate the presigned URL exactly:

  • Use the same HTTP method (usually PUT)
  • Match the Content-Type header (if you specified it when creating the URL)
  • Don’t include extra headers that weren’t signed during URL generation

内容的提问来源于stack exchange,提问作者Joey Yi Zhao

火山引擎 最新活动