AWS: s3 bucket policy does not give IAM user access to upload to bucket, throws 403 error

0

I have an S3 bucket that works perfectly with root credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) to upload files to the bucket.

I have created an IAM user.
I tried to give this IAM user the privilege of uploading files to this bucket by creating this policy and attaching it to that bucket:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::122xxxxxxxx28:user/iam-user-name"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucket-name"
        }
    ]
} 

However, when I try to upload a file, I get this error:

> PUT
> https://bucket-name.s3.region-code.amazonaws.com/images/60ded1353752602bf4b364ee.jpeg?Content-Type=image%2F%2A&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIARZARRPPIBMVEWKUW%2F20220128%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20220128T123229Z&X-Amz-Expires=300&X-Amz-Signature=dfdc3d92f6e52da5387c113ddd793990d1033fdd7318b42b2573594835c01643&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read
> 403 (Forbidden)

This is how the upload works:

  1. I generate a presigned-url in the backend:
var getImageSignedUrl = async function (key) {
  return new Promise((resolve, reject) => {
    s3.getSignedUrl(
      "putObject",
      {
        Bucket: AWS_BUCKET_NAME,
        Key: key,
        ContentType: "image/*",
        ACL: "public-read",
        Expires: 300,
      },
      (err, url) => {
        if (err) {
          reject(err);
        } else {
          resolve(url);
        }
      }
    );
  });
};
  1. Then the file is uploaded in the frontend using that url:
await axios.put(uploadConfig.url, file, {
    headers: {
      "Content-Type": file.type,
      "x-amz-acl": "public-read",
    },
    transformRequest: (data, headers) => {
      delete headers.common["Authorization"];
      return data;
    },
  });
1 Antwort
1

Hi, Good question

Could you please try the following

"Resource": [
				"arn:aws:s3:::bucket-name",
				"arn:aws:s3:::bucket-name/*"
			],

S3 buckets require one ARN at the bucket level and another one for all the objects in the bucket.

Let me know if that doesn't help, I can further look into it.

Sri

profile picture
Sri
beantwortet vor 2 Jahren
  • Thank you. That solved my problem.

  • Exactly like Sri wrote.

    action s3:PutObject works on the object level, not bucket, that's why it requires arn:aws:s3:::bucket-name/*

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen