Securely Share Images and Files in your S3 Buckets – AWS Signed URLs


Making sure that your images and files are all secure is very important, but sometimes you also want to share them. In this article we’re going to learn how to secure out the bucket before adding signed URLs to allow temporary access to our files by people we trust.

If you want to follow along then you can. You can clone this branch and continue from there:

git clone –single-branch –branch l35-signed-urls git@github.com:SamWSoftware/ServerlessYoutubeSeries.git

Securing the S3 Bucket and Images

In our serverless.yml file we need to remove the AccessControl: PublicRead field on the bucket config. This will restrict the ability to see the files within the bucket.

Next we need to make sure the images that we’re uploading are not public either. If we go to them lambdas/endpoints/imageUpload.js and find the s3 file upload then we can update that functionality. We need to start by adding the import of the top of the file.

import S3 from '../common/S3';

We then need to update the s3 write functionality, making sure to set the ACL to null.

await S3.write(buffer, key, process.env.imageUploadBucket, null, body.mime);

If we save all of this and deploy this then when we upload an image we get a access denied response when we try and access the newly uploaded images.

Adding Signed URLs

With our files secured we need to find a way to give temporary access to people that we need to.

In our common/s3.js file we can add a new method to the object. This is going to be our way of requesting a secure signed URL.

async getSignedURL(bucket, fileName, expriySeconds) {
        return s3Client.getSignedUrl('getObject', {
            Bucket: bucket,
            Key: fileName,
            Expires: expriySeconds,
        });
    },

This function takes three parameters, the bucket, file name, and expiry in seconds. This expiry is how long the signed URL will be valid for.

Back in the imageUpload.js the endpoint we can change the URL constant that used to be a template string.

const url = await S3.getSignedURL(process.env.imageUploadBucket, key, 60);

In this case, we are passing in expiry of 60 seconds and we’ll test that out later. For now, we can deploy the new function code. As we’re just updating an existing lambda we can use sls deploy -f imageUpload.

Testing

If we go back into our test image upload app, we can upload an image again. We can see that the image is uploaded as we expect and is shown on screen. If we inspect the image we can copy the image URL and paste it into a new tab. You may have noticed that it’s a lot longer than the old public URLs. This is because it has an access key and secret in the query string parameters. This is how it allows only certain people to access the file.

If you do this within 60s the new tab will contain just the image. If you wait for a short while then refresh the page you might get access denied. If you still see the image then wait for another 20s and refresh the page again.

This access denied the response shows that the expiry is up and that URL is not valid anymore. If you want to give permanent access to that file to someone you could have set the expirySeconds to null.

Sam Williams

Sam is a Serverless Obsessive who runs Complete Coding, helping developers learn Serverless and companies make the most of the competitive advantage that Serverless gives them. Previous projects include: - Designing a chat platform that currently resolves over 250,000 customer inquiries a month for international retailers and local government - Architecting a backend system to support a 3D clothing visualisation tool - Building a solution to manage millions of dollars of communication software - Designing a "Video Editing in the Cloud" platform, enabling everyone from movie studios to indie film makers to harness the power of the Cloud - without needing to be cloud experts. - Launching a profitable Serverless Startup in under 30 days He has also been teaching cloud-based software development for 5 years and has taught Serverless development to thousands of people. The Complete Coding Youtube channel now has over 15,000 subscribers and over 1 million views

Recent Posts