AWS Cloud Operations & Migrations Blog

Build a multi-account access notification system with Amazon EventBridge

While working with many of our customers, a recurring question has been “How can we be notified when users login to key accounts so we can take action if needed?” This post shows how to implement a flexible, simple, and serverless solution that creates notifications when sensitive accounts are logged in to.

Alerting on high risk account access is advised as part of multi-account best practices. And although this approach is something we recommend, customers currently must develop their own method.

In this post, we will walk you through a solution that will allow you to implement a flexible and scalable framework that can trigger notifications when users access accounts of interest, use specified roles, or leverage the root user principal in AWS account(s) or Organizational Units (OUs) they specify. The notifications generated can be emailed or sent to another AWS service to trigger additional automated actions, allowing you to reduce risk from unauthorized access to your environments.

Prerequisites

You will need to verify the following:

  • Your AWS Organization must have all features enabled.
  • Make sure you do not have an explicit deny Service Control Policy (SCP) set at the Organization level that could prevent stacksets from being deployed.
  • You must enable trusted access for stacksets to run the management account stack.

Key Concepts

Before we dive deep into this solution, let’s review some key concepts that are centric to the logic:

  • AWS root account user is the email address and password that were used to create an AWS account initially.  The AWS root account user has the highest level of privileges and its use should be restricted to a small list of actions that require it.
  • IAM identities are created using AWS Identity and Access Management (IAM) and take the form of either an IAM user with long-term credentials, or an IAM role with short-term credentials.
  • AWS accounts can contain many users and roles.
  • AWS Organizations allows for the creation and management of AWS accounts.
  • Organizational Units (OUs) are containers for accounts. An OU can also contain other OUs.
  • Root OU is the parent container for all the accounts for your organization. If you apply a policy to the root, it applies to all OUs and accounts in the organization.
  • CloudFormation Stacksets allow you to deploy and manage configurations across multiple AWS accounts.

Solution

The solution we will be walking you through details the steps needed to build a multi-account access notification system using AWS Organizations for account management, Amazon EventBridge to identify key login actions, AWS Lambda to act on the events, Amazon Simple Notification Service (SNS) to send notifications, and Amazon DynamoDB for storing configuration data. The solution is also fully compatible with AWS Control Tower.

Diagram of the solution, showing the management account, audit account, and child accounts' roles.

The LoginNotification Configuration Database DynamoDB table is where the rules are stored to determine what login activities trigger a notification. By default, you will have a single rule in the table that causes the AWS root account to trigger a notification, which will look like the following:

Default rule set for the Login Notifier deployment, showing one rule to trigger notifications for the root account logins.

Records in the LoginNotification Configuration Database have the following attributes:

“id” is what the rule applies to.  This can be an AWS account number, Organizational Unit, or Organizational root.  There is a special ID called “DEFAULT” which applies to all accounts

“inclusions” is a stringset field that contains a list of principals you want to include in your login notifications.  Principals are evaluated against the “userIdentity” field in AWS Management Console sign-in events from CloudTrail.  Items in the “inclusions” stringset are evaluated for a complete or partial match for the “userIdentity” field in the login event.

“exclusions” is a stringset field that indicates principals which should not generate notifications.  The same evaluation logic applies to exclusions as inclusions.

There are 2 reserved words in the “inclusions” and “exclusions” list

  • ROOT means the AWS root account user.
  • ALL means match all principals.

When a console login event is received it is evaluated in the following order:

  1. By default, no notifications will be sent.
  2. If the account where the login occurred is not defined in the LoginNotification Configuration database then only the “DEFAULT” rule is applied.
  3. If the account where the login occurred is defined in, or is under an OU that is defined in the LoginNotifications Configuration database then all inclusions and exclusions that apply to the account and higher-level OUs are consolidated into a combined list
  4. If any of the entries in the combined “inclusions” list are a partial or complete match for the “userIdentity” from the event, a notification will be sent, unless there is an entry in the combined “exclusions” list that also matches the “userIdentity” from the event.  “exclusions” take priority over “inclusions”.

We recommend adding additional rows beyond the default entry that fit your own best practices. You may add rules at any of four different levels: Account, OU, Root OU, and Default. Exclusions always take precedence over inclusions. As an example, consider the DynamoDB table below:

DynamoDB table showing additional examples of rules to customize the Login Notifier solution.

In this example you can see two rows that represent specific accounts (rows 1 and 3), a row that represents an OU (row 2) and the default entry (row 4).

 Let us consider the effect on account “123456789012” in this set of entries. First, we would apply the DEFAULT rule which indicates we should include ROOT logins and any with “aperson” in the login credentials. If account “123456789012” was part of “OU-ABCD-EFGHIJKLM”, we would also apply an inclusion for “athirdperson” due to that entry. And finally, since we have an entry for that account, we would apply the exclusion for “aperson” which would remove that string from our combined inclusions. We would be left with any logins for ROOT or for “anotherperson” for this account.

Walkthrough

In order to install this solution, you will need to deploy two CloudFormation stacks.  These stacks can be created in any order.

  • CentralEventBus stack.  This stack creates the EventBridge central event bus, DynamoDB tables, and Lambda functions necessary for this solution.  This should be deployed in a security audit account.  If you’re using AWS Control Tower this should be deployed in your Audit account.
  • ManagementAccount stack.  This must be deployed in your AWS Organizations management account.  This stack deploys the stackset that will deploy the EventBridge forwarding rules to your existing and new AWS accounts.  It also deploys a cross account role that the LoginNotifierParser Lambda function uses to query AWS organizations to determine which rules apply to each account.  This stack requires trusted account access with AWS Organizations to be enabled for your AWS Organization.

Step 1: Deploying the CentralEventBus stack

We’ll start with the CentralEventBus stack. You should deploy this to your Audit account, or a similar functioning account. In order to deploy the solution, sign in to the AWS Management Console and navigate to the CloudFormation console. Next, download the CentralEventBus template and save it, and deploy the solution template using Create Stack.

The CentralEventBus template takes the following parameters:

  • AWSSSOHomeRegion indicates the home region for your IAM Identity Center (successor to AWS SSO).  The default here is us-east-1.
  • CacheExpiration is the length of time (in seconds) to cache results from AWS organization.  To minimize calls to AWS Organizations and reduce execution times this solution caches information about the AWS Organizations hierarchy in a DynamoDB table.  The default expiration is 300 seconds (5 minutes)
  • EmailSubscription is the email address that will receive notification events.
  • OrganizationID is your AWS Organizations identifier.  This can be found by either navigating to the AWS Organizations console in the AWS console or by running the AWS CLI command “aws organizations describe-organization”.

You will be taken to the CloudFormation Stacks screen for your CentralEventBus stack. The deployment may take a few minutes to complete. Once completed, you will see a CREATE_COMPLETE status.

CloudFormation stacks screen showing a CREATE_COMPLETE status.

After the stack has successfully completed, the email address you used in the stack details will receive an email requesting that you confirm the subscription to the SNS notification topic. Click the link in the email while logged into the account where you deployed the CloudFormation stack.

Example of an AWS subscription confirmation notice email.

When you click on the “Confirm subscription” link you will see a confirmation screen indicating you have subscribed that email to the SNS notification topic for the login notifications.

Example of a subscription confirmed message from Amazon Simple Notification Service.

Step 2: Deploying the ManagementAccount stack

Next you will deploy the ManagementAccount stack. You should deploy this to your AWS Organizations management account. Be sure to verify you have covered the prerequisites as mentioned earlier in “Prerequisites”.

In order to deploy the solution, sign in to the AWS Management Console and navigate to the CloudFormation console. Next, download the ManagementAccountStack template and save it, and deploy the solution template using Create Stack.

The ManagementAccount template takes the following parameters:

  • CentralEventBridgeAccountID is the account ID where the CentralEventBus stack is or will be deployed.
  • CentralEventBridgeRegion is  the region where the CentralEventBus stack was deployed.
  • DeployTo is where you would want the EventBridge Notification rules to be deployed.  This can either your AWS Organizations root ID or an OU.
  • MonitoredRegions is a comma-separated list of the regions from which you want login events forwarded.  “us-east-1” must be part of this list in order to forward AWS root user logins.

You will be taken to the CloudFormation Stacks screen for your ManagementAccount stack. The deployment may take some time to complete depending on how many accounts and regions are included. Once the stack is deployed you will see a CREATE_COMPLETE for the stack name you used.

CloudFormation stacks screen showing a CREATE_COMPLETE status.

Tips:

It can be useful to run the AWS CLI command “sts get-caller-identity” from an account you’re logged into in order to see the “UserID” information you may want to key off of for your inclusion/exclusion rules.  Here is an example of the command output:

[cloudshell-user@ip-10-0-0-6 ~]$ aws sts get-caller-identity

{

    "UserId": "AROAYQDUR5EGT522XDYRZ:my-user",

    "Account": "1234567829012",

    "Arn": "arn:aws:sts:: 1234567829012:assumed-role/MyRole/my-user"

}

It also may be helpful to review “ConsoleLogin” events in the AWS CloudTrail console to help formulate your own best practice rules.

Cleanup:

In order to remove this deployed solution it is only necessary to delete both CloudFormation stacks created here. Additional costs will occur if the solution is not deleted.

The cost to implement the solution will vary based on the number of regions and accounts monitored, as well as the amount of login activity.  Please see the relevant service pricing pages for more information on pricing:

Conclusion

In this post, we showed how you can implement a flexible, simple and serverless solution for alerting on sensitive account logins as part of a best practice recommendation. This is accomplished by utilizing existing AWS CloudTrail events, AWS Organizations, Amazon EventBridge, AWS Lambda, and Amazon SNS. This allows customers to send notifications to relevant support personnel or trigger additional automation tasks based on critical events, making remediation of potential security issues a simple task.

Although we do not require AWS Control Tower for this solution, it is an account management best practice and works well with the architecture for the Login Notifier. You can read more about Control Tower in the documentation.

About the Authors

Jeff Bodey

Jeff Bodey

Jeff Bodey is a Senior Solutions Architect based in Denver, Colorado. He works with customers to help them build well architected and scalable applications in AWS. Jeff enjoys playing with gadgets and probably has entirely too many in his home.

Jeff Stockamp

Jeff Stockamp

Jeff Stockamp is a Principal Solutions Architect based in Seattle, Washington. Jeff helps guide customers as they build well architected-applications and migrate workloads to AWS. Jeff is a constant builder and spends his spare time building Legos with his son.

Thuy Uyen Tran

Thuy Uyen Tran

Uyen Tran is a Greenfield Account Solutions Architect and also part of the AI/ML TFC at AWS. She is passionate about learning and facing technical challenges. Technology, innovation, and automation are her areas of interest.

Giuseppe Zappia

Giuseppe Zappia

Giuseppe Zappia is a Senior Solutions Architect at AWS, with over 20 years of experience in full stack software development, distributed systems design, and cloud architecture. In his spare time, he enjoys playing video games, programming, watching sports, and building things.