How to enhance security on your AWS account

Most site owners use their main access and secret keys from AWS (S3 Amazon/CloudFront) to publish  videos and audios. Although this works very well, it is not that safe because if someone else gets hold of your keys, they have full access to your S3 Buckets/CloudFront distributions. To prevent this from happening, AWS introduced IAM users (Identity Access Management). If you are publishing videos or audios on your site via S3/CloudFront, this tutorial will be very interesting to you because it enhances AWS protection considerably.
Here I show you 2 methods to accomplish this in order of complexity:

  1. via CloudBerry s3 Explorer Pro
  2. via AWS console with a custom policy script

Method 1 is the easiest and safest because the IAM Manager wizard of CloudBerry S3 Explorer checks mistakes before implementation and you do not need to write code.
Method 2 is a bit more complicated since the AWS console is not exactly the most user friendly, but it works on all platforms and you can use the script for any client application as well.

What kind of IAM user do you need on your site?

Ideally, we create a user which is limited to reading files from selected buckets to display existing videos and audios on your site only.
This user won’t be able to access the AWS console, nor has it access to any buckets via client applications like CloudBerry S3 Explorer, CyberDuck, etc.
To upload and manage your media and files, you use your main access keys as usual but you won’t use them on your site anymore. This way, you isolate the “root user” with full access and work with an extremely limited user on your site.

We talk about a user, but in reality we actually just create an  IAM user in order to generate a set of access keys which are limited to reading certain buckets. With this method we protect buckets not associated with those access keys and we prevent downloads via client applications if those keys are stolen one day.
The beauty of this method is that you can use those keys also on an existing site, by simply changing the access keys in the code or via a plugin ( like S3Media Stream ).
You can do much more with an IAM user, but in this tutorial we focus on enhancing AWS protection on your site.

1. Creating an IAM user with limited access via CloudBerry S3 Explorer Pro

CloudBerry S3 Explorer Pro is a brilliant client application to manage your AWS account. It is what I call “the Photoshop” of client apps if you want a comparison. Unfortunately, it does not exist on Mac, and I have not found a comparable application for the iOS platform at this time of writing.

You need Flash Player 9 or later installed to play this s3streamingvideo

Below you find a video tutorial to work with the AWS console, but in order to do that, you need to create a policy script which is explained in the next section:

2. Creating an IAM user with limited access via AWS console

The AWS console has a set of templates to create permissions for IAM users, but there is no one suitable for this highly restricted user and using the Policy Generator is not evident since it can be quite confusing for beginners. Therefore, we work with a custom script. Copy the sample policy below and paste it into a text file. Leave the file open and view the video tutorial underneath the sample code.
Or if you want to know more about how to adapt the script, jump to the Policy script explained section in this article:

{
 "Statement": [
    {
      "Effect": "Allow",
      "Action": [
      "s3:List*",
      "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::boogerman"
       ],
       "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": "s3:Get*",
      "Resource": [
        "arn:aws:s3:::boogerman/*"
       ],
       "Condition": {}
    }
   ]
 }

You need Flash Player 9 or later installed to play this s3streamingvideo

AWS Policy script explained

This AWS policy script is a custom version that restricts an IAM user to certain buckets. It is possible to grant access to all buckets and once, but you may have other buckets with backups and sensitive files that have nothing to do with your website. Therefore, it would be best to protect those buckets.
The first part of the script below in green is meant to determine which buckets can be accessed by the IAM user.
The second part in red determines which folders are allowed for the IAM user in those buckets.
Here, “boogerman” is the name of a bucket in this example. You can replace it with your own bucket name:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::boogerman"
      ],
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": "s3:Get*",
      "Resource": [
        "arn:aws:s3:::boogerman/*"
      ],
      "Condition": {}
    }
  ]
}

If you want to add more buckets, you need to adapt both parts in the script. To adapt the policy, let’s begin with the first part:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::boogerman"
      ],
      "Condition": {}
    },
  1. Copy the red part.
  2. Go to your text file and place a comma after that particular line and enter a newline
  3. Then paste the line you just copied and adapt the name boogerman according to the bucket name you want to add, like this:
"arn:aws:s3::mybucket",
"arn:aws:s3:::mybucket2"

Note that the last line has no comma. If you want to add more buckets, repeat this process, like this:

"arn:aws:s3::mybucket",
"arn:aws:s3:::mybucket2",
"arn:aws:s3::mybucket3"

In your text file, you should now have something like this:

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::mybucket",
        "arn:aws:s3:::mybucket2",
        "arn:aws:s3:::mybucket3"
      ],
      "Condition": {}
    },

Again, note that the last bucket has no comma at the end. This indicates the list of permission has ended. If you were to leave a comma there, the policy won’t work.
We are going to do the same thing with the second part:

    {
      "Effect": "Allow",
      "Action": "s3:Get*",
      "Resource": [
        "arn:aws:s3:::boogerman/*"
      ],
      "Condition": {}
    }
  ]
}

The list of buckets should reflect the same buckets as placed in the first part:

"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket2/*",
"arn:aws:s3:::mybucket3/*"

After “mybucket”, there is a slash and an asterix. This means that the IAM user will be able to view all * folders in that bucket. You can limit the user to certain folders by replacing the asterix * with a folder name, like this:

"arn:aws:s3:::mybucket/myfolder"

In practice, you may want to give full access to a bucket, otherwise it becomes very difficult to work out which folder is allowed and which not, especially if you have several sites with each its own IAM user.
After you made changes, your policy should look more or less like this (presuming you dedicated 3 buckets to this user):

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::mybucket",
        "arn:aws:s3:::mybucket2",
        "arn:aws:s3:::mybucket3"
      ],
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": "s3:Get*",
      "Resource": [
        "arn:aws:s3:::mybucket/*",
        "arn:aws:s3:::mybucket2/*",
        "arn:aws:s3:::mybucket3/*"
      ],
      "Condition": {}
    }
  ]
}

If you only want to dedicate one bucket, use the original script and change the name “boogerman” into your bucket name in part 1 and 2.

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:List*",
        "s3:Get*"
      ],
      "Resource": [
        "arn:aws:s3:::mybucket"
      ],
      "Condition": {}
    },
    {
      "Effect": "Allow",
      "Action": "s3:Get*",
      "Resource": [
        "arn:aws:s3:::mybucket/*"
      ],
      "Condition": {}
    }
  ]
}

Compare this script with what you did, checking especially the comma’s. Does it look as it should?
If so, you are ready to implement this policy via the AWS console or any client application.

Leave a Comment