Diego Rey
Diego Rey

Reputation: 5

S3 bucket policy to set a folder readable by a referring URL, and another folder only available to AWS user

We have a structure with a Laravel app running in URL www.example.com and connected to a bucket with 3 folders inside.

folder_a
folder_b
folder_c

Ideally, we would like the app to be able to:

Also, folder_b and folder_c should be absolutely forbidden from internet (not listing folder, nor getting an object even knowing the URL) At the same time, the IAM user should be able to access everything, upload/download/edit/delete everything.

We have tried lots of bucket policies without success. We have successfully created the IAM user, and our Laravel app is already sending objects to the S3.

NOTE: This is not about Laravel configuration, it's about S3 bucket policies. The app is already sending objects to S3 correctly, and all objects are public now

Upvotes: 0

Views: 552

Answers (2)

Rohan
Rohan

Reputation: 1

Give bucket public access by removing check from block public

then this bucket policy works:

// this one make sure only download api calls from www.example.com/example.com are allowed
    {
        "Effect": "Allow",
        "Principal": "*",
        "Action": [
            "s3:GetObject"
        ],
        "Resource": [
            "arn:aws:s3:::<yourbucket>/folder_a/*"
        ],
        "Condition": {
           "StringLike": {"aws:Referer":["http://www.example.com/*","http://example.com/*"]}
        }
    }

Upvotes: 0

congbaoguier
congbaoguier

Reputation: 1045

Assuming eventually, you would like to get rid of the public accessibility of your S3 bucket, because it is generally a bad idea, unless you are only allowing some static, harmless files.

Here is the bucket policy:

{
    "Version": "2012-10-17",
    "Statement": [
        // this one make sure only ListBucket api calls from laravel user are allowed
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::1234567890:user/<laravel_iam_user>"
            },
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::<yourbucket>"
            ]
        },
        // this one make sure only upload api calls from laravel user are allowed
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::1234567890:user/<laravel_iam_user>"
            },
            "Action": [
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::<yourbucket>/folder_a/*",
                "arn:aws:s3:::<yourbucket>/folder_b/*",
                "arn:aws:s3:::<yourbucket>/folder_c/*"
            ]
        },
        // this one make sure only download api calls from www.example.com/example.com are allowed
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::<yourbucket>/folder_a/*"
            ],
            "Condition": {
               "StringLike": {"aws:Referer":["http://www.example.com/*","http://example.com/*"]}
            }
        }
    ]
}

Edit: since the OP actually want public access on part of the bucket, should not check all 4 public access block settings.

Upvotes: 0

Related Questions