How to Build and Maintain an Effective AWS Security Posture

Foreword & Guest Author Bio

As part of this ongoing series, SentinelOne is excited to present a series of guest blogs from cloud security experts covering their views on cloud security best practices. First in this series is the following blog from Aidan Steele, where he outlines his views on an introductory approach to AWS security posture.

Aidan is a security engineer at Cash App and an AWS Serverless Hero. He is an avid AWS user, having first got started on the platform with EC2 in 2008. Sixteen years later, EC2 still has a special place in his heart, but his interests now are in containers and serverless functions – blurring the distinction between them wherever possible.

He enjoys finding novel uses for AWS services, especially when they have a security or network focus. This is best demonstrated through his open source contributions on GitHub, where he demonstrates interesting use cases via hands-on projects. Aidan regularly shares his thoughts and new projects (sometimes useful, sometimes just for fun) on his blog and X account.

Introduction

With great cloud power comes great cloud security responsibility. AWS has added hundreds of new services, thousands of new APIs and many new approaches to how to maintain a proper security posture over the years. In this article, I share a few different methods on how to approach it. Some are well-established best practices, some are less well-known, and others I rarely see taken advantage of in all but the most mature companies.

Use Multiple AWS Accounts

A common mistake I see in companies of all sizes is using too few AWS accounts. At a minimum, I would highly recommend that you create separate AWS accounts for production workloads and pre-production workloads. There are multiple benefits to this, and they’re not all just about security.

The first benefit is that you can minimize the chance of production downtime or data loss (e.g. due to untested automation), while maximizing your developers’ productivity by allowing them to experiment confidently and safely in a “development-only” account. Developers will be more confident to evaluate new ideas, knowing that they can’t accidentally bring down production.

A secondary benefit is that it gives you an easier way to view and manage costs. You can easily identify how much you are spending on development versus production and implement different kinds of cost saving measures in each environment.

Use AWS Organizations

AWS Organizations provides an easy way to manage multiple AWS accounts. Rather than having to go through the “new AWS account” sign-up flow and juggling multiple bills, AWS Organizations allows you to create new accounts in a couple of clicks or a single API call. There are a few things to keep in mind when using AWS Organizations.

  • Keep in mind that one AWS account is designated as the “management account” for an organization. You really want to have zero workloads running in this account and provide as little access to it as possible, because it contains the keys to your whole kingdom.
  • This means that if you are setting up an organization for the first time in an account you’ve been using for years – stop! Instead, create a brand new AWS account the “old-fashioned way” and create an organization in that account. This becomes your management account.
  • Finally, use your management account to send an invitation to your existing account to join the new organization. Your security team will thank you for doing this in the years to come.

Creating a “Security” AWS Account & Delegate Administrative Tasks to It

Calling back to using the management account as little as possible, note that AWS makes this achievable by allowing you to designate an account in your organization as the “delegated administrator” for particular organization-level services. By default the administrator account is your management account. Instead, I recommend you create an AWS account dedicated to all “security” tasks and delegate administration of services to it wherever possible.

Setting Up an Organization-Level CloudTrail

CloudTrail is the definitive audit log for almost everything that happens in AWS. You should enable it as early as possible. After delegating CloudTrail administration to the security account, you can create an organization-wide CloudTrail in that account. This means that a record of all AWS APIs invoked in all AWS accounts in your organization will be stored in an S3 bucket for easy querying.

If you want to start querying immediately, you can enable CloudTrail Lake. This provides an easy way to query your CloudTrail logs using SQL. For more cost savings, you can instead use AWS Athena to query the CloudTrail logs stored in S3. Both of these options are much better than the “event history” available in the regular CloudTrail web console, because that view only provides very limited filtering – and only for the last 90 days.

Using Organizational Units (OUs) Effectively

AWS Organizations allows you to group AWS accounts together into organizational units (OUs). You can then attach service-control policies to particular OUs. For large companies, it can be tempting to reflect your corporate org chart in the AWS web console. Don’t do this! Instead, group accounts by their environment, e.g. create a “development” OU and place all your pre-production AWS accounts there. Create a “production” OU and place all your production AWS accounts there. This makes it easier to enforce SCPs like “no deleting databases in production”.

In addition to development and production OUs, another couple of common OUs are “security” and “acquisitions”. The security OU is where you put the aforementioned security AWS account, and other delegated administrator accounts if you choose to further subdivide them. The acquisitions OU is especially useful for larger companies that acquire other companies. During an acquisition you often will invite your acquisition’s AWS accounts to join your organization. You don’t know quite how they use AWS yet and you don’t want to break anything by enforcing SCPs too early. The acquisition OU is effectively a staging area for these accounts until you are confident you can safely move them into your regular OU hierarchy.

Use IAM Identity Center

This service was previously known as “AWS Single Sign-On”. Regardless of its name, using it will make life easier for you and your developers – and more secure, too. IAM Identity Center can either plug into your existing SSO solution, or stand alone. You can assign your developers access to whichever AWS accounts they need access to in your organization. You can give them power-user access in development accounts and read-only access in production. Best of all, they don’t need to store any AWS credentials on their development machine – they can log into any account using the AWS CLI aws sso login command.

Leverage IAM Roles Over IAM Users

If you follow the guidance in the previous section, you are already well on your way to making IAM users obsolete at your company. IAM users are all too often implicated in security breaches. This is because they have access keys that are easy to identify and are long-lived: they don’t expire automatically like IAM role credentials. However, there are still some other places you might be tempted to use them – let’s discuss them and the alternatives.

Use federation where possible, especially for third party integration. There are broadly three ways you can federate access into AWS. All of these options are preferable to deploying IAM users, and which one to use depends on the use case:

  • OIDC – This is often used for CI/CD tools, e.g. GitHub Actions, GitLab, BuildKite, etc. You can create a “CI” role in your AWS account and have your CI system assume that role via an OIDC trust relationship. Bonus: CloudTrail will show auditors which build pipeline made particular API calls when you do this.
  • SAML – This is often used for humans assuming a role in AWS from your SSO provider. Technically this is how IAM Identity Center works. SAML federation can also be useful for federating from on-premises Active Directory workloads to AWS.
  • Roles Anywhere – The newest option available, this is the marketing name for X.509 certificate-based federation. A good rule of thumb is that you shouldn’t consider this unless you already have a mature, established X.509 public key infrastructure deployed across your company.

Using these three approaches means that you will have no need for IAM users. Still have on-premises machines and none of the above options work for you? Consider Systems Manager hybrid activations.

De-Duplicate Your Event-Driven Automation

A common pattern is to use EventBridge and Lambda functions for security-related automation. For example, you might have a Lambda function that is triggered when an EC2 instance is launched, and it automatically terminates the instance if something is misconfigured. People often deploy these Lambda functions into every AWS account and region that they run workloads in. This technically works, but can be burdensome to deploy and maintain.

Instead, I would recommend deploying this Lambda function once to a single AWS account and region. You configure it to be triggered by the relevant event rule, and configure the event bus to allow events to be forwarded from other AWS accounts in your organization. You can then use a CloudFormation service-managed stack set to deploy an EventBridge rule and IAM role in every account in your organization. Those rules will forward events to your single, centralized bus. The role can be assumed by your Lambda function when it needs to take action in response to an event. Now you can iterate on your security automation quicker and easier than ever!

Use IAM Role Paths

Paths are a convenient way to organize IAM roles. Often you will deploy a collection of roles to every account in your organization. You want to ensure that developers don’t accidentally change the configuration of these roles and want to write an SCP to protect them. Rather than having to enumerate the name of each protected role in your SCPs, you can instead put all roles in an /org-admin/ path and write a short SCP to prevent modification of roles with the ARN arn:aws:iam::*:role/org-admin/*.

Use the Power of Security Group References

In the pre-cloud world, we used to assign IP addresses from workload-specific IP ranges. Some people like to carry this over to AWS, but there’s a better option. Instead of a security group rule that says “anything with IP address 10.1.2.x/24 can access this RDS database”, you can instead rely on the fact that workloads can have multiple security groups attached.

You can create a “database client” security group and write a security group rule on the RDS instance that says “anything with the source security group sg-1234 can access this RDS database”. This grants you more flexibility and makes the purpose of security group rules more apparent.

Conclusion | The SentinelOne Perspective

As always, Cloud Security is a shared responsibility. While cloud providers secure the underlying infrastructure, it’s crucial for developers and operations teams to ensure they secure their functions, data, and access policies. SentinelOne’s recommendation is to leverage Well Architected Frameworks where possible, to ensure environments are built with secure-by-design principles.

Additionally, Cloud Native Application Protection Platforms, like SentinelOne’s Cloud Native Security, can assist cloud and security teams by detecting and prioritizing cloud risk. Our CNAPP is able to detect misconfigurations across cloud services, infrastructure and cloud identity, as well as vulnerabilities, and provides evidence-based insight into cloud risks that can be externally exploited.

Next in our guest blog series, cloud security engineer Don Magee will go into the next level of detail on account, role and credential management in AWS and more, with his post covering 6 AWS Security Blind Spots.