AWS Root User Security:

Guide to best-practice and notifications

by Paul Corley, Solution Architect

AWS Root User Security
In this blog, we’ll explore the topic of securing the root user in AWS and introduce a solution for immediate informative notification of Root Activity, allowing a swift response.

transACT works to the AWS Well-Architected Framework, which provides architectural best practices for designing and operating workloads on AWS. The framework is structured around six key pillars: Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimisation, and Sustainability. We carry out many Well-Architected Reviews (WAR) of company workloads, and one of the most common High-Risk Issues we come across is a lack of security for the root user.

The root user is the most privileged user in an AWS account, with full administrative access to all resources within the account, and in some cases, cannot be constrained by security policies.

This blog will focus on creating a solution that notifies you when root user activity is detected and ends by going through the best practices for securing the root user. One of the most significant issues working in Operations is getting a meaningful notification that can be understood immediately. This solution uses a Lambda function to parse the root usage event detail into a simple email.

The screenshot below shows email previews detailing root user activity of the process of password recovery and login. The root activity and the friendly account name or alias (in this case, ‘paul’) are shown in the subject header. More detail is given within the email body text, including the local time of the activity and a complete JSON event dump.

The Solution Architecture is shown below:

  1. The root user logins into the AWS Management Console
  2. The login is recorded in a global CloudTrail trail which is set to Read and Write All Events. Root API login is logged in US-EAST-1 and this solution is deployed in that region
  3. An Event Rule exists in EventBridge that monitors root API activity and detects an AWS API call or AWS Console Sign In via CloudTrail by Root. This triggers a Lambda function
  4. An AWS Lambda Function is passed the event and after working out the local time creates a Simple Notification Service (SNS) that details the login (see below) and the time it happened. The function expects that an Account Allas has been set for the Account Id and includes error handling if one has not been set
  5. The SNS message is sent to operational users via email
  6. The email details the Root Activity that occurred using the account friendly name/alias and the local time with the full event details

This solution is created by deploying a CloudFormation template which is publicly available in this GitHub Repository. The template is extensively commented to improve understanding.

Pre-Requisites

Before Running the CloudFormation Script, Follow These Steps:

1. Create an Account Alias (Friendly Name)
To improve clarity and ease of reference, create an Account alias for your AWS Account ID. The alias can be 3-63 characters long and may include hyphens. A common convention is to use -iam, -dev, or -prd after your company name (e.g., company-iam, company-dev, company-prd). Adding an alias to an Account is easy: login to the management console and enter IAM in the Search bar, this will take you to the IAM dashboard. On the right-hand side, under AWS Account is Account alias, then choose Create to create an alias.

2. Set the Region to us-east-1
Ensure the region is set to “us-east-1” when deploying the CloudFormation script. You can do this by selecting the region in the CloudFormation Console or setting the region variable in your CLI command using the “–region” option.

CloudFormation Script

The CloudFormation script is commented for ease of understanding with # Section Number followed by a heading such as ‘# Section 1. Parameters’. You should refer to the Solution Architecture to see the flow between the resources created.

1. Parameters
The script takes five parameters with allowed patterns to control input where necessary. The parameters are listed below:

EmailAddress:
SNSTopicName:
LambdaTimeout:
LambdaFunctionName:
CloudTrailBucketName:

The Cloudformation code creates the following Resources:

2. SNS Topic
It creates a Simple Notification Service Topic with the SNSTopicName inputted through parameters. The topic uses email, and the target email address comes from the EmailAddress parameter.

3. CloudTrail trail with target S3 bucket and bucket policy
A CloudTrail trail is created that is MultiRegion, includes Management Events and has ReadWrite set to All. There is a DependsOn statement to ensure that the BucketPolicy is created before the trail. The trail will deliver data to an S3 bucket, which uses the BucketName parameter.

The S3 bucket is created with ServerSide encryption, public access blocked, and access control set to public. A write access bucket policy is also created that gives CloudTrail the rights to get the bucket ACLs and put objects in the bucket.

4. Event Rule that monitors root API activity
An EventRule is created that checks for Root API calls and Sign Ins to the Console. This rule when it matches the event pattern, triggers a call to Lambda which is detailed as the Target.

5. Lambda to parse event detail and send informative email to SNS Topic
The Lambda function has been designed to be deployed from CloudFormation and avoids using external Python libraries, which would require deployment packages. The Lambda function makes use of the Python Libraries listed below:

Python LibraryDescription
jsonProvides methods for working with JSON (JavaScript Object Notation) data in Python.
boto3Software Development Kit (SDK) to interact with AWS services programmatically.
loggingAdds logging functionality essential for troubleshooting and auditing.
osAllows you to interact with the underlying operating system
botocoreLower-level interaction with AWS services which boto3 in built on. The ClientError component is used for error handling.
datetimeProvides date and time functionality
dateutilExtends the functionality of the datetime library, specifically with the tz component which allows for timezone operations
The Lambda function is passed the SNS topic ARN as an environment variable and carries out extensive debugging of the API event which is important for troubleshooting.

It determines the local time which in this case is UK and Ireland and provides debug information for troubleshooting.

It uses a boto3 call to IAM to work out the account alias from the Account Id, providing debug information with error handling if no account alias exists.

The function creates a user-friendly email message detailing the root activity followed by the full event detail, which is shown below (redacted for security reasons). The event detail can be used for further investigation.

6. Lambda Role, Policies and Permissions
A policy and role are created to enable the Lambda function to access and write to CloudWatch. The function needs permission to publish to SNS and ListAccountAlias which allows it to look up the Alias given an account number. A policy is also added that enables the EventRule to invoke it.

Securing the Root User Best Practices

You will need to make sure that the use of the root user is controlled and audited to avoid intentional or accidental damage when the account is used.

The following are best practices that should be used in securing the root user:

  1. Accurate Contact Information: Avoid tying the root user account to individual email addresses, which can lead to issues during staff changes. Instead, use a distribution list that provides redundancy.
  2. Dedicated Phone Number: Assign a dedicated phone number exclusively for the root user account to enhance security.
  3. Multi-Factor Authentication (MFA): Enable MFA and set up a dedicated MFA device, preferably a hardware device, with at least one backup device. This safeguards against the loss or unavailability of MFA methods.
  4. Strong Password: Use a complex and strong password for the root user account to prevent unauthorized access.
  5. Two-Person Rule: Implement a two-person rule to ensure that no single individual can access all the credentials and MFA methods required for root user access, adding an extra layer of security.
  6. Avoid Access Keys: Refrain from creating Access Keys for the root account and promptly remove any that exist. The root account should not be used for programmatic access.
  7. Monitoring and Detective Controls: Implement robust monitoring and detective controls to detect any usage of root credentials. Consider AWS services like Amazon GuardDuty, AWS Control Tower, or a notification solution, such as the one presented here.

Summary

In this blog, I have demonstrated how to enhance the security of the root user and provide informative notifications of root user activity. It’s crucial to regularly review the security measures in place for the root user to ensure continued access to the account while maintaining the security of email addresses, phone numbers, credentials, and MFA.

If you would like to discuss a Well-Architected Review, securing the root user or any aspect of your AWS account, please contact cloud@transactts.com.

News