Protecting images on Amazon S3 through Rails app
Amazon S3 allows users to store their objects in buckets. All buckets and their objects are associated with Amazon ACLs(Access Control Policies). ACL is a set of permissions of read, write and update on bucket and its objects..
In this approach, we see how to set permissions to S3 objects using appropriate Amazon’s ACL and allow a time-limited access to a protected object by using a “pre-signed” request to prevent its reuse.
Amazon S3 allows to construct query strings for requests to access private Amazon S3 data. It allows us to retrieve a “pre-signed” request encoded as a URL and limits it by an expiration_time, which means the request data will not be accessible after a limited time.
The required authentication elements are specified as query string parameters namely AWSAccessKeyId, Expires and Signature
Following is an example query string authenticated Amazon S3 REST request:
Date: Mon, 10 Dec 2012 18:36:56 +0000
See Amazon S3 documentation, under section “Query String Request Authentication Alternative” for more details on it.
If you need to upload and protect your images in your Rails app to Amazon S3, you can use aws-s3 gem.
aws-s3 gem for Rails has a method ‘store’ in class AWS::S3::S3Object which is used to upload an object to a bucket as follows:
:content_type => mime_type,
:access => :authenticated_read
You can set access to your bucket using Amazon’s ACLs or bucket policy. Amazon accepts the following ACLs:
Here we’ve used a authenticated_read bucket access policy which means only authenticated Amazon’s S3 users can see the S3 objects.
The library also has a method url_for in class AWS::S3::S3Object
which generates the said authenticated url (described above) for an object as follows:
By default, authenticated urls expire after 5 minutes from the time they were generated. Expiration options can be specified with expires_in options:
# (Expires in 3 hours)
bucket ,expires_in => 60 * 60 * 3)
You can specify whether the url should go over SSL with the :use_ssl option:
# Url will use https protocol
bucket, use_ssl => true)
Using this approach, the S3 data is protected using appropriate access control policy and the end-users can access your data on S3 with the help of Amazon S3 REST request which is query string authenticated. It is further limited with short timeouts after which the data becomes inaccessible which adds to security of your data on S3.