Programster's Blog

Tutorials focusing on Linux, programming, and open-source

AWS - Create Specific Keys For Security Access

I hear stories about people leaking their full access keys on Github and then being slammed with a massively expensive bill because someone found it and spawned a load of EC2 instances, either to just be malicious, or to mine "free" cryptocurrency for themselves. Yes it's super dumb to post keys on Github, but "stuff happens" and I'm sure keys will leak out in other ways as well.

I believe the real tragedy is that people are being lazy and using a single key that has access to everything, across all of their codebases. If you generate keys for each service, and each key only grants access to what the service needs, you can mitigate a lot of the potential damage. Imagine just how much less damage would have been done if the key that was leaked just had read-only access, or only full access to just one service like Route53?

Even if you are not worried about outside threats, having limited keys can be a great way of reducing risk with new employees or trainees. Giving them restricted keys to work with may prevent them from writing code that accidentally spawns a lot of ec2 instances or accidentally terminates existing ones.

Below are the steps showing just how easy it is to create restricted keys for your services.


Search for the IAM service and click on it to open it up.

Click on Users, and then click Add User.

Enter the name for this "user". I called it route-53 because this user will just have full access to Route53, but afterwards I realized this was a mistake. It would be much better to put the name of the service that is going to use these credentials (like ssl-generator-route53). It is important to create a set of credentials per service, even if they have the same access rights. This way you can delete the credentials later if that service/codebase ever gets compromised or you need to increase/decrease the access rights later. Then you know that your actions will only affect that one service/codebase and don't need to worry about the others suddenly not working.

Click add existing policies directly unless you know already have a user that you want to copy, or a group in place.

Enter the name(s) of the service(s) that you want to add permissions to. In this case I just want to have access to Route53, so I entered that. Then tick the policies that apply.

If your service can get by with just reading data, be sure to tick those instead of full access. It's best to be restrictive as possible and upgrade permissions later as or when they are needed rather to err on the side of flexibility. A lot more damage that can be done with write access than read-only access. Always be thinking about the consequences of a malicious user getting hold of these credentials.

Click Review after having selected your policies.

You will be shown a summary of the permissions you are granting. Click Create User.

You will be shown the access credentials that "user" now has. Plug these into your software in order for it to gain the access rights you just selected. Be sure to click the "show" link to view the key.

You will now see the "user" in your user list. If your codebase ever becomes compromised (such as accidentally publishing the keys to Github), then rest easy knowing that you can just select the user and click delete. I have already deleted the user I created for this tutorial even though I made sure not to show the "secret" key.

Custom Policies

In the steps above, I just selected from policies Amazon had already prepared for me. If you're prepared to get down and dirty, you can actually create custom policies that are more fine-grained so that you can limit your user to performing certain actions, rather than having write access to everything in a resource. I will list custom policies that prove useful to me below:

EC2 Snapshotting

If you need a user that just has the ability to create AMI images (which requires snapshotting of the ebs volumes), then this is what you need (courtesy of a post on serverfault):

  "Effect": "Allow",
  "Action": [
  "Resource": [