AWS Database Blog

Use guardrails to protect DynamoDB tables

Access control to AWS services and resources should be governed by the security principles of zero trust and least-privilege. Zero trust requires that users are strongly authenticated and fine-grained authorization is enforced before gaining access to resources. Least-privilege is a principle of granting only the permissions required to complete a task. Least-privilege is also an AWS Well-Architected best practice for building securely in the cloud and it’s recommended that you apply the principle of least-privilege when working with Amazon DynamoDB. For instance, DynamoDB users can delete tables with an API call or equivalent operations on the AWS Management Console or by using SDKs. As a result, during the course of routine maintenance operations, database administrators (DBAs) and other users might delete a table by mistake. A DBA might issue the wrong command or intend to delete a temporary table but accidentally delete a production table. Accidental deletion of a table can lead to disruptions in business operations until the table is recovered from backups.

In this post, you learn how to reduce the chance of a table in DynamoDB being accidentally deleted. This is done by creating AWS Identity and Access Management (IAM) policies to restrict access to a DynamoDB table in a single AWS account. You then learn how to apply the restrictions and scale least-privilege practices in a multi account environment or when using Infrastructure as Code (IaC).

Prerequisites

The examples in this post assume that you have an AWS account set up and are logged in with permission to create new IAM roles and policies, and have an existing DynamoDB table that you want to protect. The multi-account example further assumes that you have an existing AWS organization set up with an account used for DynamoDB workloads and access to administer the organization.

Embed guardrails using IAM

Applying the principles of zero trust and least-privilege restricts the DynamoDB DeleteTable operation to only authorized users. DynamoDB is fully integrated with IAM, which lets you use IAM to tailor access control to resources and operations in DynamoDB. With IAM roles, policies, and groups, you can implement a security configuration to verify that DynamoDB resources are only accessed and modified according to your defined authorization policies. This includes preventing accidental table deletion.

There are multiple approaches that you can take to use IAM to control access. In this first example, you use IAM policies to restrict table deletion by creating a policy and attaching it to an existing IAM principal. We recommend using IAM roles and mapping those roles to users and groups from your corporate identity provider, but an IAM principal can also be a user or group.

To create and apply an IAM policy to restrict access

  1. Sign in to the AWS Management Console and open the IAM console.
  2. Select the Policies tab and then choose Create policy.
  3. Choose the JSON tab and enter your policy. The following example permissions policy denies the DeleteTable action for the tables in the US West (Oregon) us-west-2 Region for account 111122223333:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyTableDelete",
            "Effect": "Deny",
            "Action": "dynamodb:DeleteTable",
            "Resource": "arn:aws:dynamodb:us-west-2: 111122223333:table/*"
        }
    ]
}

Note: See To use the JSON policy editor to create a policy in Creating IAM policies for more details.

  1. Enter a name under Policy name.
  2. [Optional] Enter a description and tag.
  3. Still in the IAM console, navigate to your user, group, or role and attach the policy that you just created.

To restrict delete operations for indexes or modification operation for provisioned throughput or DynamoDB Streams, you can apply a Deny on Action dynamodb:UpdateTable.

The following example’s permissions policy denies the UpdateTable action for the tables in the us-west-2 Region for account 111122223333:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyTableUpdate",
            "Effect": "Deny",
            "Action": "dynamodb:UpdateTable",
            "Resource": "arn:aws:dynamodb:us-west-2: 111122223333:table/*"
        }
    ]
}

Add multi-account access control with service control policies

The examples in the previous section work in a single AWS account. However, you might be running DynamoDB tables in multiple AWS accounts and need a mechanism to enforce access control in a consistent manner across all accounts. This is where service control policies (SCPs) come to the rescue.

You can use SCPs as guardrails to centrally control the maximum permissions for accounts in your AWS organization. AWS Organizations is an account management service that lets you consolidate multiple AWS accounts into an organization that you create and centrally manage. Refer to the AWS Organizations User Guide to learn more about Organizations and its foundational constructs such as organization, root, organizational unit (OU), and account. SCPs help you ensure your accounts stay within your organization’s access control guidelines.

You can use an SCP to create a policy that denies the DynamoDB DeleteTable operation for the accounts in an OU. With SCPs, you can apply a policy at the root, OU, or account level. Understanding policy inheritance is important when dealing with SCPs. For more information, refer to Understanding policy inheritance.

In this example, you create an SCP and attach it to an OU to restrict the DynamoDB DeleteTable operation for the accounts in that OU.

To create an SCP to restrict the DeleteTable operation

  1. Sign in to the management account to create an SCP (or use the Delegated Administration feature for AWS Organizations to access from a separate account). The management account is the account that you used to create the organization.
  2. On the Organizations console, choose Policies in the navigation pane.
  3. Choose Service control policies.
  4. Choose Create new service control policy.
  5. Enter a name under Policy name.
  6. Optionally, enter a description and tag.
  7. For the statement section, enter the following policy:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DDB DeleteTable SCP",
            "Effect": "Deny",
            "Action": [
                "dynamodb:DeleteTable"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
  1. Choose Create policy.

To attach an SCP to a target

  1. On the Organizations console, access the policy that you created and navigate to the Targets tab.
  2. Choose Attach. Figure 1 that follows shows the AWS Organizations console view for attaching a new target to the SCP.
Figure 1: Attach a new target to an SCP

Figure 1: Attach a new target to an SCP

You can see the OUs and the accounts under the OU. You can apply the policy that you created at the root level, OU level, or account level.

  1. For this walkthrough, attach the policy to one of the accounts. In this example, the account is Workload Account1 in the Sandbox OU.
  2. Choose Attach policy. Figure 2 shows an example of the AWS Organizations console view.
Figure 2: Attach a policy to an account

Figure 2: Attach a policy to an account

With the SCP in effect, attempting to delete the table using the console in Workload Account 1 fails for principals in the account, regardless of whether their IAM permissions grant them access, as shown in Figure 3 that follows. If you do want to delete the table, an administrator would need to move the account to a maintenance OU that doesn’t have the SCP in place.

Figure 3: Deletion request fails

Figure 3: Deletion request fails

“Your delete table request encountered issues. User: arn:aws:sts:: 111122223333:assumed-role/Admin is not authorized to perform: dynamodb:DeleteTable on resource: arn:aws:dynamodb:us-west-2: 111122223333:table/Test with an explicit deny in a service control policy.”

Prevent accidental deletes triggered by IaC

Depending on your operating model, DynamoDB tables can be deployed through the console or programmatically through IaC. AWS CloudFormation is an IaC solution that lets you model, provision, and manage AWS and third-party resources. When using IaC, in addition to access control guardrails, you can use a CloudFormation deletion policy to preserve resources.

CloudFormation lets you specify a deletion policy that determines what happens to a resource if the stack is deleted. This policy also applies to stack update operations that lead to resources being deleted from stacks. For example, removing the resource from a CloudFormation stack template deletes the resource unless the deletion policy is set to Retain.

To keep a resource when the stack is deleted or modified, specify Retain for that resource. When editing a CloudFormation template, you can set the DeletionPolicy to Retain for any resource. The following snippet is an example for a DynamoDB table in a JSON CloudFormation template:

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Resources" : {
    "myTable" : {
      "Type" : "AWS::DynamoDB::Table",
      "DeletionPolicy" : "Retain"
    }
  }
}

See How do I retain some of my resources when I delete an AWS CloudFormation stack? for more detailed examples of using the DeletionPolicy in both JSON and YAML formatted CloudFormation templates.

Conclusion

In this post, you learned how to use IAM policies and roles to prevent DynamoDB DeleteTable operations. You also learned how to extend this prevention method to multiple accounts using SCPs. Finally, you learned how to add an additional protection using AWS CloudFormation deletion policies to prevent DynamoDB tables from being deleted when a stack is changed or removed.

Reviewing and evaluating the risks associated with your existing DynamoDB tables is the first step in determining the IAM policies, SCPs, and CloudFormation deletion policies to use to improve the durability of your tables. Review these items, and then read about the latest AWS Backup features for DynamoDB, which help you centrally manage and automate DynamoDB data protection.


About the Authors

Anup Sivadas is a Principal Solutions Architect at Amazon Web Services and is based out of Arlington, Virginia. With 18 + years in technology, Anup enjoys working with AWS customers and helps them craft highly scalable, performing, resilient, secure, sustainable and cost-effective cloud architectures. Outside work, Anup’s passion is to travel and explore the nature with his family.

Randy DeFauw is a Senior Principal Solutions Architect at AWS. He holds an MSEE from the University of Michigan, where he worked on computer vision for autonomous vehicles. He also holds an MBA from Colorado State University. Randy has held a variety of positions in the technology space, ranging from software engineering to product management. In entered the Big Data space in 2013 and continues to explore that area. He is actively working on projects in the ML space and has presented at numerous conferences including Strata and GlueCon.

Ashwin Venkatesh is a Senior Product Manager for Amazon DynamoDB at Amazon Web Services, and is based out of Santa Clara, California. With 25+ years in product management and technology roles, Ashwin has a passion for engaging with customers to understand business use cases, defining strategy, working backwards to define new features that deliver long-term customer value, and having deep-dive discussions with technology peers. Outside work, Ashwin enjoys travel, sports and family events.