S3 - Anonymous Upload - Key prefix

Eric Anderson picture Eric Anderson · Aug 11, 2012 · Viewed 9.7k times · Source

I am trying to understand exactly how to setup a bucket that is generally private but allows anonymous uploads with restrictions. The specific criteria are:

  • The bucket is mostly private and requires my key/secret to add/remove/update/list files.
  • There is a "directory" (i.e. key prefix) called "incoming" that will allow anonymous users to upload content to but not list.
  • The bucket has a one day expiration on all content. As a bonus I would like the "incoming" directory to have a 30 minute expiration although if that is not possible a one day expiration for the whole bucket will do.
  • Files with the "incoming" prefix would be limited in size per object.
  • I might want to also limit objects with the "incoming" prefix to only certain content types.

Questions I have are:

  1. Would it be better to simply create two buckets. One for my incoming files and one for my own personal processing and storage?
  2. What would the code look like that for a file to be uploaded into the incoming directory. Ideally I would like to avoid a dependency on a S3 library and just use HTTP calls. Bonus points if you can show me the right direction on this in Ruby. :)

The expiration seems settable via the S3 Management Console but is only limited to 1 day as the smallest expiration. Can I put a decimal in that field? Permissions seem to apply to an entire bucket instead of just a prefix. This is making me think I just need two buckets. If I keep with one bucket I think I need to create an IAM policy and apply that to the bucket but it is beyond my limited knowledge of S3 and I want to ensure I don't leave a hole in the permissions that allow people to do more than I want them to.

I have found lots of documentation on doing anonymous uploads to S3 via a HTTP form post. I could adapt that into code but I am wondering since I am in application code (and not a HTTP form post) is there an easier way?

Answer

Michal Klouda picture Michal Klouda · Aug 27, 2012

What you describe can be implemented within one bucket. You can allow anonymous access to specific folder via bucket policy, check examples or use AWS Policy Generator. In your case it could look something like this:

{
    "Version": "2008-10-17",
    "Id": "Policy1346097257207",
    "Statement": [
        {
            "Sid": "Allow anonymous upload to /incoming",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::[your_bucket]/incoming/*"
        }
    ]
}

It is also possible to upload files to your bucket anonymously using a simple html form:

<form action="http://[your_bucket].s3.amazonaws.com/" method="post" enctype="multipart/form-data">
    <input type="hidden" name="acl" value="public-read" />
    Name: <input type="text" name="key" value="incoming/[filename]" /><br/>
    File: <input type="file" name="file" /> <br />
    <input type="submit" name="submit" value="Upload" />
</form>​

S3 browser based uploads are described here in detail.