AWS IAM: Securing your Infrastructure

Written by: Florian Motlik

When developing a new product and finding that product market fit every team needs to move fast. Especially startups, as the whole future of the company is dependent on quickly finding the people who pay for your product.

Amazon Web Services has been an incredible tool for startups and other teams to build their application and infrastructure quickly. These teams often have a stronger background in development than proper system operations.

AWS provides great tools to handle keys, authentication and security, but many teams haven’t looked into them, as more pressing issues often come up.

We want to introduce a couple of concepts and features that will help you make your infrastructure more secure, while taking only minimal effort.

Identity and Access Management (IAM), the heart of AWS security

IAM, Identity and Access Management, is the core of the AWS security system. It allows you to manage users, groups and different roles in your infrastructure. You can create different functional groups with different permissions and add people to these groups. This makes it easy to change the permissions once people are moving into other groups and don’t need access to every part of the system any more.

You can attach several policies to a user, group or role which cover access to different AWS services or different resources.

The IAM documentation is easy to read and definitely interesting to skim through once. It’s available as HTML, PDF or for your Kindle, so you can even read it during your commute.

Do not use the default key provided to your AWS account

The first and most important measure you can take with AWS is to not use the default key provided to your AWS account. This key has full access to every system. This is a major security issue, as leaking this key would mean you give somebody else access to every part of your infrastructure. Additionally over time it will be hard to determine where you use the key in your infrastructure, so once you want to change the key you have to search through all of your infrastructure without any pointers.

Creating Users or groups for the different puposes of your application makes this part self documenting, so whenever you want to change your keys you know which part of your infrastructure is concerned.

Create a User account for each person

UPDATE

In this section we mean creating different users in IAM, not different Amazon/AWS accounts. You will have one main AWS account, but inside of that account you can create different users that access the resources of that main account with the credentials they need. Thanks to Mike in the comments for the feedback.

As a first step logging into the main AWS account should be discouraged. Every person in your team that needs access to AWS should get their own account with different credentials. By adding these users to specific groups you can add or remove permissions easily without losing track of who is able to do what. Do not put permissions on specific users, but create a group for the permission, as it is self documenting and can be changed for everyone. In the following image we created different groups for admins, finance and API access.

The users in our finance group have access to our billing statements only. Even in case their account is broken into there is no way to access any infrastructure.

The second important step to secure your user accounts is enabling two factor authentication for all of them. Everyone who logs into the system and has access to important resources needs to have two factor enabled. As the admin you can check if two factor is enabled in the users detail page on IAM. You can enable this right away for every new hire in your team.

For example the following user doesn’t have two factor enabled. By adding it and following through with the Wizard you can increase your security a lot.

Using several keys for roles with specified capabilities

As we said before you should never use the main key of your AWS account for accessing the API. This doesn’t mean to just create an admin user and use this key everywhere.

Users, groups and roles should only have the specific permissions that are necessary to accomplish one specific task. Don’t mix them. Maybe you want to put a task onto another server in the future. If you combine permissions you know have to split them into different groups or roles. You really should keep those apart from the beginning.

Don’t use keys inside EC2 instances

A lesser known feature of IAM is roles and how to connect them to different parts of your infrastructure. For example if you have an app server that should be able to read or upload data to S3. In the past you might have added the AWS secret and access key into the machine, so it can use those to access S3.

Instead you can create a role that includes the permission to upload to specific S3 buckets and set the EC2 instance to use this role. If you use the AWS SDK’s for different languages they will automatically generate temporary keys that have the same permissions as defined in the role.

Create a Role in IAM

First you start by creating a new role in IAM for EC2. You can create roles for different services like Opsworks that can make calls to the AWS API for you.

Then you create a policy that let’s you access a specific S3 Bucket

Import the following policy into the wizard:

#!ruby
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1385708770000",
      "Effect": "Allow",
      "Action": [
        "s3:Get*",
        "s3:List*",
        "s3:DeleteObject",
        "s3:PutObject",
        "s3:PutObjectAcl",
        "s3:PutObjectVersionAcl"
      ],
      "Resource": [
        "arn:aws:s3:::testbucket/*",
        "arn:aws:s3:::testbucket"
      ]
    }
  ]
}

This will allow read and write access only to the testbucket, but no other S3 bucket. You can read more about Policies in the IAM doc. You can limit a policy to specific instances, buckets or other infrastructure items with ARNs, Amazon Resource Names, like we did in the above example with the testbucket. AWS has extensive documentation about ARNs

Now we want to connect the role to the EC2 instances. Whenever you start a new instance you set the IAM Role of that instance to the role we just created.

Here we set the role to checkbot

Now whenever you call the AWS API you don’t have to provide any keys as they will be automatically created for you with the correct permissions. From now on no more keys are necessary inside the instance, which makes the whole setup a lot cleaner and easier to use.

Enable Cloudtrail

Cloudtrail is a new service that was released at the AWS:reInvent last November. It will automatically log every call to the AWS API into a S3 Bucket. This can help with auditing in the future.

It takes a few clicks and less than 30 seconds to set up, will cost nearly nothing (you only pay for the S3 bucket, but not for Cloudtrail) and can save you in the future. Just do it!

Conclusions

AWS is an incredibly large and complex system, but provides easy first steps to implement your product and security. There are a few steps and practices that you can follow to increase your security a lot, without too much effort. Of course in the longer term you need to invest into security and starting with reading the IAM documentation is a good start.

As startups we want to move fast, build product and ship to our customers. All of this is necessary and important to get the company started. With a few easy fixes you can increase the security early, so you don’t leak your customers data for preventable reasons.

Ship long and prosper!

Further Information

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.