<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matheus Almeida Costa</title>
    <description>The latest articles on DEV Community by Matheus Almeida Costa (@almeidamatheus).</description>
    <link>https://dev.to/almeidamatheus</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1152214%2Fdfb940fc-de1d-4c04-8ae3-ab99d5e921b0.jpg</url>
      <title>DEV Community: Matheus Almeida Costa</title>
      <link>https://dev.to/almeidamatheus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/almeidamatheus"/>
    <language>en</language>
    <item>
      <title>How to Ensure Security Tool Connectivity on EC2 Across AWS Accounts with Automated Security Group Compliance</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Fri, 06 Mar 2026 02:20:12 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-ensure-security-tool-connectivity-on-ec2-across-aws-accounts-with-automated-security-group-mbh</link>
      <guid>https://dev.to/aws-builders/how-to-ensure-security-tool-connectivity-on-ec2-across-aws-accounts-with-automated-security-group-mbh</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Cloud security operations often require ensuring consistent and compliant network access for security tools across hundreds of Amazon EC2 instances distributed across multiple AWS accounts and regions.&lt;/p&gt;

&lt;p&gt;In large-scale environments managed through AWS Organizations, what seems like a simple requirement can quickly become operationally complex.&lt;/p&gt;

&lt;p&gt;Many security tools depend on network connectivity to perform their functions. Without the correct inbound rules configured on EC2 Security Groups, these tools cannot reach the instances they are supposed to monitor and access.&lt;/p&gt;

&lt;p&gt;Common examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Privileged Access Management (PAM)&lt;/strong&gt; such as BeyondTrust or CyberArk, which require network connectivity to EC2 instances to rotate credentials and manage privileged sessions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Vulnerability management platforms&lt;/strong&gt; such as Qualys or Tenable, which require network connectivity to perform authenticated vulnerability scans and deeper security assessments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration compliance and hardening tools&lt;/strong&gt; which connect via SSH or RDP to EC2 instances to verify system configurations, validate security baselines, and assess compliance with standards such as CIS Benchmarks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In large multi-account AWS environments, maintaining this connectivity manually becomes unmanageable.&lt;/p&gt;

&lt;p&gt;The traditional manual approach quickly breaks down for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Slow onboarding&lt;/strong&gt;: Every new AWS EC2 on any AWS account required manual configuration of Security Group rules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operational fragility&lt;/strong&gt;: If someone accidentally removed a rule, the security tool immediately lost access reducing visibility into the environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of scalability&lt;/strong&gt;: Managing scanner IP ranges across dozens of AWS accounts and multiple regions through the console simply doesn't scale.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the environment grows, these issues compound, creating gaps in security monitoring and increasing operational overhead for security teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;p&gt;The goal was to guarantee network accessibility in a reliable and automated way for approved security tools to EC2 instances across all AWS regions and accounts.&lt;/p&gt;

&lt;p&gt;The solution needed to meet the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatic coverage for new resources&lt;/strong&gt;: Newly launched EC2 instances should always receive the required connectivity without manual intervention.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operational scalability&lt;/strong&gt;: The mechanism must work seamlessly across multiple regions and accounts without requiring per-account configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auto remediation configuration&lt;/strong&gt;: If a rule is accidentally removed, it should be automatically restored.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized management&lt;/strong&gt;  : Security teams should be able to update security tools IP ranges in a single location and propagate those changes across all accounts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solution Architecture
&lt;/h2&gt;

&lt;p&gt;To achieve this, I built an automated daily compliance mechanism that validates and enforces security group rules across the entire AWS Organizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Diagram
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2j1czezruh1kei92bhi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2j1czezruh1kei92bhi.png" alt="Automated workflow ensuring security group compliance and accessibility for security tools" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following diagram illustrates the high-level architecture used to automate Security Group compliance across multiple AWS accounts and regions.&lt;/p&gt;

&lt;p&gt;The automation runs from a dedicated security account, where AWS Lambda functions handle two main tasks: building an inventory of AWS accounts by assuming a role in the Organizations management account and performing remediation actions by assuming roles in member accounts.&lt;/p&gt;

&lt;p&gt;In this example, the diagram shows two fictional member accounts (Account X and Account Y) containing EC2 instances and Security Groups. In real environments, this approach can scale to dozens or even hundreds of accounts.&lt;/p&gt;

&lt;p&gt;The architecture also demonstrates a multi-region setup (&lt;code&gt;us-east-1&lt;/code&gt;, &lt;code&gt;us-east-2&lt;/code&gt;, and &lt;code&gt;sa-east-1&lt;/code&gt;), where Security Groups reference regional Prefix Lists to allow connectivity from centralized security tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Components
&lt;/h3&gt;

&lt;p&gt;The solution relies on a small set of AWS services working together to provide centralized control, automation, and scalability across all accounts in the organization.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS Lambda&lt;/strong&gt;: Acts as the automation engine. The function assumes cross-account IAM roles to audit EC2 Security Groups and automatically remediate missing rules when necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Amazon S3&lt;/strong&gt;: Stores a daily-generated inventory of all AWS accounts. This inventory is used by the automation workflow to determine where audits and remediations should be executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS VPC Prefix Lists&lt;/strong&gt;: Provides a centralized and scalable way to manage the IP ranges used by security tools. Instead of hardcoding IPs in Security Group rules, the rules reference a Prefix List. This allows security teams to update the IP ranges in a single place and AWS automatically propagates the changes to every Security Group referencing the list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS Organizations&lt;/strong&gt;: Provides the centralized account structure that allows the automation to discover and operate across all AWS accounts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS Resource Access Manager (RAM)&lt;/strong&gt;: Enables the Prefix List to be shared with all accounts in the organization, allowing Security Groups in any account to reference the centralized list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AWS CloudFormation StackSets&lt;/strong&gt;: Used to deploy the required IAM roles across all AWS accounts in the organization. This ensures that newly created accounts automatically receive the permissions required for the automation to operate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. AWS account inventory collection
&lt;/h4&gt;

&lt;p&gt;A scheduled AWS Lambda function (triggered by Amazon EventBridge) runs in the management account and queries AWS Organizations to retrieve the list of active accounts. The function also enumerates enabled AWS regions and stores this inventory in an Amazon S3 bucket. Maintaining this inventory allows the automation to dynamically adapt as new accounts are added or removed from the organization.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Cross-Account Security Group Audit and Remediation
&lt;/h4&gt;

&lt;p&gt;The main Lambda function consumes the account inventory stored in S3 and iterates through each AWS account and region. Using cross-account role assumption, the function inspects EC2 instances and their associated Security Groups to verify whether inbound access from the authorized Prefix List is allowed. If the required rule is missing, the Lambda automatically injects the appropriate inbound rule into the Security Group, ensuring the instance remains accessible to the approved security tools.&lt;/p&gt;

&lt;p&gt;As a result, EC2 instances will have a Security Group rule similar to the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu46zgrh9ialtu3pwlpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu46zgrh9ialtu3pwlpm.png" alt="Security Group rule example" width="800" height="103"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the rule allows all ports to simplify connectivity for security tools. However, depending on your environment and the requirements of each tool, you can restrict the rule to only the specific ports that are required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Steps
&lt;/h2&gt;

&lt;p&gt;The full implementation for this project is available in the &lt;a href="https://github.com/almeida-matheus/aws-ec2-security-group-automation-compliance" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is a high-level guide to deploy this solution in a multi-account AWS environment.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create the Prefix List
&lt;/h4&gt;

&lt;p&gt;Start by creating a Prefix List in each region where your workloads run. This list will contain the IP ranges used by your security tools and will be referenced by Security Group rules instead of hardcoding individual IP addresses. &lt;/p&gt;

&lt;p&gt;With this approach, security teams can update IP ranges centrally through the Prefix List, without needing to modify Security Groups across multiple accounts or regions.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Share the Prefix List Across Accounts
&lt;/h4&gt;

&lt;p&gt;Use AWS Resource Access Manager (RAM) to share the Prefix List with all accounts in your AWS Organization.&lt;/p&gt;

&lt;p&gt;This allows Security Groups in other accounts to reference the centralized Prefix List. After sharing, Security Groups in all accounts can reference the Prefix List.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Deploy the Cross-Account IAM Role
&lt;/h4&gt;

&lt;p&gt;The automation Lambda requires permissions to describe and modify Security Groups across multiple AWS accounts.&lt;/p&gt;

&lt;p&gt;To enable this, use AWS CloudFormation StackSetsto deploy a receiver role in all accounts of the organization. This ensures that newly created AWS accounts automatically receive the required role.&lt;/p&gt;

&lt;p&gt;The following custom IAM policy is attached to the role:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AllowEC2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"ec2:DescribeInstances"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"ec2:DescribeSecurityGroups"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"ec2:AuthorizeSecurityGroupIngress"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AllowOrganizations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"organizations:ListAccounts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"organizations:ListAccountsForParent"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The role must also allow &lt;code&gt;sts:AssumeRole&lt;/code&gt; from the central security account where the Lambda runs.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Deploy the Lambda functions
&lt;/h4&gt;

&lt;p&gt;Deploy the two Lambda functions in the security account. &lt;/p&gt;

&lt;p&gt;The first Lambda is responsible for building an inventory of AWS accounts by retrieving the list of accounts from AWS Organizations and storing this inventory in Amazon S3. &lt;/p&gt;

&lt;p&gt;The second Lambda consumes this inventory, assumes the cross-account role in each account, audits EC2 Security Groups across regions, and automatically adds the missing inbound rule referencing the Prefix List when necessary.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Deploy the EventBridge Schedule
&lt;/h4&gt;

&lt;p&gt;Create an Amazon EventBridge rule to trigger the Lambda functions on a schedule, for example once per day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extra: Security by Default with IaC
&lt;/h2&gt;

&lt;p&gt;While the automation remediates missing rules, the best control is preventing the misconfiguration from happening in the first place.&lt;/p&gt;

&lt;p&gt;To achieve this, a security-by-default approach can be implemented in the Infrastructure as Code layer using Terraform.&lt;/p&gt;

&lt;p&gt;When new EC2 Security Groups are created, the rule allowing access from approved security tools is added by default. This ensures that new workloads are compliant from the moment they are deployed, reducing the need for remediation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example Terraform Configuration
&lt;/h4&gt;

&lt;p&gt;Instead of hardcoding scanner IP addresses directly in Security Group rules, the configuration references AWS Managed Prefix Lists. This allows security teams to update scanner IP ranges centrally without modifying infrastructure code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow security scanning tools"&lt;/span&gt;
  &lt;span class="nx"&gt;prefix_list_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;security_pl&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because Managed Prefix Lists are regional resources in AWS, the Terraform configuration dynamically selects the correct Prefix List ID based on the region where the infrastructure is deployed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;security_pl&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lookup&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pl-xxx"&lt;/span&gt;
  &lt;span class="s2"&gt;"us-east-2"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pl-yyy"&lt;/span&gt;
  &lt;span class="s2"&gt;"sa-east-1"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"pl-zzz"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach ensures that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security tools have immediate access to newly created instances.&lt;/li&gt;
&lt;li&gt;IP changes are managed centrally through the Prefix List instead of individual Security Group rules.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Maintaining network access for security tools across multiple AWS accounts can quickly become an operational burden if handled manually.&lt;/p&gt;

&lt;p&gt;By combining Managed Prefix Lists, cross-account automation, and Infrastructure as Code, we transformed this into a scalable and self-healing control.&lt;/p&gt;

&lt;p&gt;Instead of relying on manual Security Group management, connectivity for security tooling becomes part of the platform itself automatically enforced and continuously verified.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>cloudsec</category>
      <category>automation</category>
    </item>
    <item>
      <title>AWS Security Services Overview</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Sun, 01 Feb 2026 02:54:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/aws-security-services-overview-1ko8</link>
      <guid>https://dev.to/aws-builders/aws-security-services-overview-1ko8</guid>
      <description>&lt;h1&gt;
  
  
  AWS Security Services
&lt;/h1&gt;

&lt;p&gt;This post provides a complete overview of AWS security services, serving as a reference for professionals who work with Cloud Security.&lt;/p&gt;

&lt;p&gt;The goal is to give a clear understanding of what each service does, how it fits into an AWS security strategy, and when it makes sense to use it in real environments.&lt;/p&gt;

&lt;p&gt;Each section is organized by category with practical examples and common use cases that reflect real-world scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identity &amp;amp; Access Management.&lt;/li&gt;
&lt;li&gt;Data Protection.&lt;/li&gt;
&lt;li&gt;Network Security.&lt;/li&gt;
&lt;li&gt;Threat Detection &amp;amp; Monitoring.&lt;/li&gt;
&lt;li&gt;Application Security.&lt;/li&gt;
&lt;li&gt;Compliance &amp;amp; Governance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Identity &amp;amp; Access Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Identity and Access Management (IAM)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/iam" rel="noopener noreferrer"&gt;IAM&lt;/a&gt; defines who can do what in your AWS environment. It provides authentication (via users, roles, and federated identities) and authorization (via policies) for every AWS service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A security team designs IAM roles for developers to deploy Lambda functions only in non-production environments. Each role has a limited set of permissions (using wildcards carefully) and temporary credentials are used instead of long-term access keys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the principle of least privilege grant only what’s needed.&lt;/li&gt;
&lt;li&gt;Replace IAM users with roles and temporary credeBest Practicesntials.&lt;/li&gt;
&lt;li&gt;Enforce MFA for all privileged accounts.&lt;/li&gt;
&lt;li&gt;Use IAM Access Analyzer to identify unused or overly broad permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AWS IAM Identity Center (AWS SSO)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/iam/identity-center/" rel="noopener noreferrer"&gt;IAM Identity Center&lt;/a&gt; is a centralized access management for all your AWS accounts.&lt;br&gt;
It connects with identity providers like Okta, Azure AD, or Google Workspace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
In an enterprise setup, employees log in once using their corporate credentials and can access multiple AWS accounts through the AWS Console Portal, with fine-grained permissions mapped by group (Dev, SecOps, Finance, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Organizations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/organizations" rel="noopener noreferrer"&gt;AWS Organizations&lt;/a&gt; is a centralized way to manage user access across multiple AWS accounts and business applications. It integrates with identity providers (like Okta, Azure AD, or Google Workspace) for single sign-on (SSO).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company with 10 AWS accounts configures IAM Identity Center with Azure AD. Developers log in once with their corporate credentials and access the AWS accounts they’re assigned to, based on group membership.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use group-based access instead of assigning permissions to individuals.&lt;/li&gt;
&lt;li&gt;Map corporate directory groups to AWS accounts and permission sets.&lt;/li&gt;
&lt;li&gt;Enable MFA and session timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Resource Access Manager (RAM)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/ram" rel="noopener noreferrer"&gt;RAM&lt;/a&gt; allows you to securely share AWS resources (like subnets, Transit Gateways, or Route 53 zones) across accounts or within your AWS Organization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A central network account shares a Transit Gateway with multiple VPCs across other accounts, allowing secure and controlled inter-VPC communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share only necessary resources with trusted accounts.&lt;/li&gt;
&lt;li&gt;Review resource shares regularly for unused ones.&lt;/li&gt;
&lt;li&gt;Use tagging to track ownership and accountability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon Cognito
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/cognito" rel="noopener noreferrer"&gt;Cognito&lt;/a&gt; handles authentication and authorization for web and mobile apps, supporting user pools (sign-up/sign-in) and identity pools (federation with social or enterprise IdPs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A startup builds a mobile app where users can sign in using Google or Apple ID. Cognito manages identity federation and issues temporary AWS credentials for accessing backend APIs securely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable MFA and password policies.&lt;/li&gt;
&lt;li&gt;Protect access tokens using HTTPS and secure client SDKs.&lt;/li&gt;
&lt;li&gt;Use Cognito triggers (Lambda) to validate user data or enforce additional checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pay per monthly active user (MAU) and per authentication request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Directory Service
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/directoryservice/" rel="noopener noreferrer"&gt;Directory Service&lt;/a&gt; provides managed Microsoft Active Directory (AD) in AWS or integrates AWS resources with your existing on-premises AD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An enterprise migrates its Windows-based workloads to AWS. By deploying AWS Managed Microsoft AD, administrators can apply the same group policies and authentication rules as in their on-premises environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS Managed Microsoft AD when you need full AD capabilities.&lt;/li&gt;
&lt;li&gt;Limit domain admin access and use dedicated admin accounts.&lt;/li&gt;
&lt;li&gt;Monitor directory logins using CloudWatch or CloudTrail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Charged per directory type and instance hours.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Protection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Secrets Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/secrets-manager" rel="noopener noreferrer"&gt;AWS Secrets Manager&lt;/a&gt; is a managed service for storing, rotating, and retrieving database credentials, API keys, and other secrets securely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Instead of embedding credentials in a Lambda environment variable, the function retrieves the password from Secrets Manager at runtime. Automatic rotation ensures passwords stay up to date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable automatic secret rotation using Lambda.&lt;/li&gt;
&lt;li&gt;Restrict IAM access to specific secrets.&lt;/li&gt;
&lt;li&gt;Use encryption with KMS for all stored secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per secret stored and per 10,000 API calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Private Certificate Authority (CA)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/private-ca/" rel="noopener noreferrer"&gt;AWS Private Certificate Authority (CA)&lt;/a&gt; is a managed service for issuing and managing private SSL/TLS certificates for internal use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An enterprise uses Private CA to issue certificates for internal APIs, IoT devices, and internal dashboards eliminating reliance on public certificate providers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate certificate renewal and deployment via ACM integration.&lt;/li&gt;
&lt;li&gt;Enforce short certificate lifetimes to reduce exposure risk.&lt;/li&gt;
&lt;li&gt;Restrict who can issue certificates with IAM policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly fee per CA + per certificate issued.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Certificate Manager (ACM)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/certificate-manager/" rel="noopener noreferrer"&gt;AWS Certificate Manager (ACM)&lt;/a&gt; Simplifies the provisioning, deployment, and renewal of SSL/TLS certificates for AWS resources (ALB, CloudFront, API Gateway, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A website hosted on CloudFront automatically uses ACM-issued certificates to enable HTTPS, with zero manual renewal effort.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use DNS validation for automation.&lt;/li&gt;
&lt;li&gt;Prefer ACM for public-facing endpoints.&lt;/li&gt;
&lt;li&gt;Combine with AWS WAF for secure web delivery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public certificates are free; private ones incur cost via Private CA.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon Macie
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/macie" rel="noopener noreferrer"&gt;Amazon Macie&lt;/a&gt; uses machine learning to identify and protect sensitive data (like PII, financial data, or credentials) in Amazon S3.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company stores millions of files in S3. Macie scans the data and alerts the security team when PII is detected in unexpected locations, triggering remediation workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schedule automatic scans of critical buckets.&lt;/li&gt;
&lt;li&gt;Use Macie findings to enforce Config remediation rules.&lt;/li&gt;
&lt;li&gt;Integrate with Security Hub for centralized visibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per GB of data classified and objects monitored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Key Management Service (KMS)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/kms" rel="noopener noreferrer"&gt;AWS KMS&lt;/a&gt; manages encryption keys for AWS services and custom applications, allowing encryption at rest and in transit with centralized control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A financial team encrypts S3 and RDS data using customer-managed CMKs, ensuring only specific IAM roles can use them for decryption. CloudTrail logs all KMS usage for auditability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use customer-managed CMKs for sensitive data.&lt;/li&gt;
&lt;li&gt;Rotate keys automatically.&lt;/li&gt;
&lt;li&gt;Enable key usage logging in CloudTrail.&lt;/li&gt;
&lt;li&gt;Enforce access policies to prevent key misuse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per key and per API request (encryption/decryption).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS CloudHSM
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/cloudhsm/" rel="noopener noreferrer"&gt;AWS CloudHSM&lt;/a&gt; is a dedicated Hardware Security Module that gives you full control over your cryptographic keys and operations. It’s ideal for compliance-heavy industries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A payments company processes card transactions that must comply with PCI DSS. It uses CloudHSM to generate and store encryption keys in an isolated, FIPS 140-2 Level 3–compliant environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use CloudHSM when compliance requires exclusive control of keys.&lt;/li&gt;
&lt;li&gt;Combine with KMS custom key store if you need hybrid integration.&lt;/li&gt;
&lt;li&gt;Plan redundancy HSM clusters span multiple Availability Zones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hourly cost per HSM instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Payment Cryptography
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/payment-cryptography/" rel="noopener noreferrer"&gt;AWS Payment Cryptography&lt;/a&gt; provides on-demand cryptographic processing for payment systems, including key management and transaction signing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A fintech uses AWS Payment Cryptography to perform secure PIN generation and key exchange with banks, ensuring compliance with PCI PIN standards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use with CloudHSM for regulated workloads.&lt;/li&gt;
&lt;li&gt;Restrict access using IAM conditions and audit logs.&lt;/li&gt;
&lt;li&gt;Rotate cryptographic keys periodically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per cryptographic operation and per key.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Network and Application Protection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Web Application Firewall (WAF)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/waf/" rel="noopener noreferrer"&gt;AWS WAF&lt;/a&gt; protects web applications from common exploits like SQL injection, cross-site scripting (XSS), and malicious bots. It operates at layer 7 (HTTP/HTTPS) and integrates with CloudFront, API Gateway, and Application Load Balancer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An online retail application exposes an API through API Gateway. AWS WAF inspects incoming traffic and blocks requests containing suspicious patterns (like “UNION SELECT” or script injections), preventing data leaks and service disruptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use AWS Managed Rule Groups to defend against OWASP Top 10 vulnerabilities.&lt;/li&gt;
&lt;li&gt;Create rate-based rules to throttle suspicious traffic and prevent brute-force attacks.&lt;/li&gt;
&lt;li&gt;Regularly review logs in CloudWatch or Kinesis Firehose for visibility.&lt;/li&gt;
&lt;li&gt;Deploy different WAF Web ACLs for staging and production environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Charged per Web ACL, rule, and number of requests inspected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Shield
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/shield" rel="noopener noreferrer"&gt;AWS Shield&lt;/a&gt; provides managed protection against Distributed Denial of Service (DDoS) attacks. It offers two tiers Shield Standard (automatic and free) and Shield Advanced (enhanced detection and mitigation with 24/7 support).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A fintech company hosts its public-facing APIs behind CloudFront. During a DDoS attempt, AWS Shield Advanced automatically detects abnormal spikes in traffic and engages AWS’s DDoS Response Team (DRT) to mitigate the attack while maintaining availability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Shield Advanced for mission-critical workloads (e.g., e-commerce, financial APIs).&lt;/li&gt;
&lt;li&gt;Combine with WAF for application-layer defense.&lt;/li&gt;
&lt;li&gt;Regularly test DDoS resilience with simulated events.&lt;/li&gt;
&lt;li&gt;Monitor metrics in CloudWatch DDoSDashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shield Standard: Free (included by default).&lt;/li&gt;
&lt;li&gt;Shield Advanced: Monthly subscription + data transfer usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Network Firewall
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/network-firewall" rel="noopener noreferrer"&gt;AWS Network Firewall&lt;/a&gt; a managed, scalable firewall that inspects traffic at the VPC level and blocks or allows traffic based on stateful and stateless rules.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A large organization builds a central inspection VPC where Network Firewall analyzes all traffic between business units using AWS Transit Gateway. Security teams manage policies globally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralize firewalls in shared network accounts.&lt;/li&gt;
&lt;li&gt;Log all traffic to CloudWatch Logs or S3.&lt;/li&gt;
&lt;li&gt;Use domain-based and Suricata-compatible rule groups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per firewall endpoint-hour and GB processed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Firewall Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/firewall-manager/" rel="noopener noreferrer"&gt;AWS Firewall Manager&lt;/a&gt; is a centralized management for WAF, Shield, and Network Firewall policies across multiple AWS accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A security team applies a standard WAF rule set to every CloudFront distribution in the organization using Firewall Manager policies, ensuring consistency across environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrate with AWS Organizations for unified control.&lt;/li&gt;
&lt;li&gt;Tag resources consistently for policy targeting.&lt;/li&gt;
&lt;li&gt;Use for compliance enforcement (e.g., mandatory WAF).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per policy per region.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Threat Detection &amp;amp; Monitoring
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS CloudTrail
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/cloudtrail/" rel="noopener noreferrer"&gt;AWS CloudTrail&lt;/a&gt; records every API call and management event in your AWS environment, providing visibility into who did what and when. It’s fundamental for auditing, incident response, and compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A developer accidentally grants public access to an S3 bucket. CloudTrail logs the API call, capturing the user identity, source IP, and timestamp. The security team uses these logs to investigate and roll back the change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable CloudTrail across all accounts using AWS Organizations.&lt;/li&gt;
&lt;li&gt;Store logs in S3 with encryption and set lifecycle policies for retention.&lt;/li&gt;
&lt;li&gt;Integrate with CloudWatch Logs or Security Lake for monitoring.&lt;/li&gt;
&lt;li&gt;Use CloudTrail Insights to detect unusual activity patterns automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One management trail per region is free.&lt;/li&gt;
&lt;li&gt;Additional trails and data events (e.g., S3 object access, Lambda invocations) incur cost per 100,000 events.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon GuardDuty
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/guardduty" rel="noopener noreferrer"&gt;Amazon GuardDuty&lt;/a&gt; provides continuous, intelligent threat detection for your AWS environment. It analyzes CloudTrail logs, VPC Flow Logs, and DNS logs to identify suspicious activity using machine learning and threat intelligence feeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Your security team receives a GuardDuty finding showing an EC2 instance communicating with a known crypto-mining domain. An EventBridge rule triggers a Lambda function that isolates the instance by removing its IAM role and updating the security group.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable GuardDuty at the organization level for centralized visibility.&lt;/li&gt;
&lt;li&gt;Automate incident response workflows using EventBridge and Lambda.&lt;/li&gt;
&lt;li&gt;Regularly review findings in Security Hub and suppress known safe activities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Based on the volume of data analyzed (per GB of logs).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Security Hub
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/security-hub/" rel="noopener noreferrer"&gt;AWS Security Hub&lt;/a&gt; aggregates and prioritizes findings from multiple AWS security services (like GuardDuty, Inspector, and Macie) and third-party tools. It gives you a unified view of your security posture across all AWS accounts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A compliance officer enables AWS Foundational Security Best Practices in Security Hub. The tool automatically checks for common misconfigurations such as unencrypted S3 buckets or unused IAM access keys and produces consolidated compliance scores.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable Security Standards (e.g., CIS AWS Benchmark, PCI DSS).&lt;/li&gt;
&lt;li&gt;Integrate with AWS Organizations for centralized management.&lt;/li&gt;
&lt;li&gt;Use custom insights to filter high-priority findings for your environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per compliance check and per finding ingested.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon Detective
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/detective" rel="noopener noreferrer"&gt;Amazon Detective&lt;/a&gt; simplifies the process of investigating and understanding the root cause of security issues by automatically collecting and correlating data from GuardDuty, CloudTrail, and VPC Flow Logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A GuardDuty alert shows potential credential compromise. The security team uses Detective to trace which IAM user performed the unauthorized API calls and what resources were affected, visualizing relationships over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable Detective in accounts where GuardDuty is active.&lt;/li&gt;
&lt;li&gt;Use it for incident post-analysis, not real-time response.&lt;/li&gt;
&lt;li&gt;Retain data for the default 12 months for full investigation context.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per GB of data processed monthly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon Inspector
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/inspector" rel="noopener noreferrer"&gt;Amazon Inspector&lt;/a&gt; provides continuous vulnerability scanning for EC2 instances, container images in ECR, and Lambda functions. It identifies software vulnerabilities (CVEs) and insecure configurations automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Inspector detects an outdated OpenSSL library on EC2 instances. The findings are sent to Security Hub, which triggers an SNS notification to the DevOps team for remediation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable automatic scanning for new workloads.&lt;/li&gt;
&lt;li&gt;Integrate Inspector findings with ticketing systems (like Jira).&lt;/li&gt;
&lt;li&gt;Use tags to include/exclude workloads from scanning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Based on resource type and number of assessments per month.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Security Lake
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/security-lake/" rel="noopener noreferrer"&gt;AWS Security Lake&lt;/a&gt; centralizes security data from AWS services and third-party sources into a data lake built on S3. It normalizes data into the Open Cybersecurity Schema Framework (OCSF) for analytics and SIEM integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An enterprise collects logs from GuardDuty, CloudTrail, and EDR tools into Security Lake, then queries them with Amazon Athena for security analytics and incident correlation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use lifecycle policies to control storage costs.&lt;/li&gt;
&lt;li&gt;Integrate with Athena or OpenSearch for detection and dashboards.&lt;/li&gt;
&lt;li&gt;Segment access by team or data type (SOC, Compliance, Forensics).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per GB of data ingested and stored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Security Incident Response
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/security-incident-response/" rel="noopener noreferrer"&gt;AWS Security Incident Response&lt;/a&gt; a set of AWS services, playbooks, and automations that help organizations prepare for, detect, and recover from security incidents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company sets up an incident response workflow: GuardDuty detects a threat → EventBridge triggers Lambda → instance is quarantined → forensics team uses CloudTrail logs for investigation → snapshots are preserved for evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build automated runbooks using Step Functions or Systems Manager.&lt;/li&gt;
&lt;li&gt;Predefine response actions for different incident categories.&lt;/li&gt;
&lt;li&gt;Regularly test your response plan through simulations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depends on the AWS services used (no direct cost for the framework).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Application Security
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Signer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://docs.aws.amazon.com/signer/latest/developerguide/Welcome.html" rel="noopener noreferrer"&gt;AWS Signer&lt;/a&gt; digitally signs code artifacts to ensure integrity and trust before deployment. It’s often used for Lambda functions, container images, and IoT applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A DevOps team signs Lambda function packages with Signer before deployment. At runtime, the function’s integrity is verified automatically, ensuring no tampering occurred during delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrate Signer into your CI/CD pipeline.&lt;/li&gt;
&lt;li&gt;Rotate and protect signing keys with KMS.&lt;/li&gt;
&lt;li&gt;Sign only verified and tested artifacts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per signing job.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Security Agent
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://aws.amazon.com/security-agent/" rel="noopener noreferrer"&gt;AWS Security Agent&lt;/a&gt; continuously scans workloads and applications for vulnerabilities and misconfigurations throughout the development lifecycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;:&lt;br&gt;
During CI/CD, the Security Agent detects that an ECS task definition exposes unnecessary ports. The pipeline blocks the deployment until the issue is fixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Embed scans into your development pipeline.&lt;/li&gt;
&lt;li&gt;Combine with Inspector for runtime checks.&lt;/li&gt;
&lt;li&gt;Use findings to educate teams on secure configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Based on scan frequency and resource usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Amazon Verified Permissions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/verified-permissions" rel="noopener noreferrer"&gt;Amazon Verified Permissions&lt;/a&gt; A fine-grained authorization service that lets applications make real-time access decisions based on centrally managed policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A banking application uses Verified Permissions to determine whether a user can view or modify specific accounts. Authorization policies are stored centrally, ensuring consistent enforcement across microservices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep authorization policies centralized and version-controlled.&lt;/li&gt;
&lt;li&gt;Design policies that reflect real business logic, not only technical access.&lt;/li&gt;
&lt;li&gt;Combine with Cognito or IAM for authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Charged based on authorization request volume.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Compliance &amp;amp; Governance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Config
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/config/" rel="noopener noreferrer"&gt;AWS Config&lt;/a&gt; records the configuration state of AWS resources and continuously evaluates them against compliance rules and baselines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Config detects that an S3 bucket becomes public. A Lambda remediation function is triggered automatically to restore compliance by blocking public access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Config Conformance Packs for CIS or NIST compliance.&lt;/li&gt;
&lt;li&gt;Enable across all accounts via AWS Organizations.&lt;/li&gt;
&lt;li&gt;Integrate Config findings with Security Hub for unified reporting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per configuration item recorded and per compliance evaluation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Audit Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/audit-manager/" rel="noopener noreferrer"&gt;Audit Manager&lt;/a&gt; automates the collection of compliance evidence, mapping AWS resource data to controls for frameworks such as SOC 2, ISO 27001, or PCI DSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A compliance officer creates an assessment based on ISO 27001. Audit Manager automatically collects encryption settings, IAM configurations, and logging evidence to prepare audit-ready reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use prebuilt control frameworks.&lt;/li&gt;
&lt;li&gt;Assign ownership of each control to specific stakeholders.&lt;/li&gt;
&lt;li&gt;Review reports regularly before formal audits.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Per active assessment per month.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Artifact
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/artifact/" rel="noopener noreferrer"&gt;AWS Artifact&lt;/a&gt; provides on-demand access to compliance reports and agreements such as SOC, ISO, and PCI certifications for AWS services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A security team downloads AWS’s PCI DSS attestation report from Artifact to include in their compliance documentation when onboarding a new client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep reports updated for each audit cycle.&lt;/li&gt;
&lt;li&gt;Store downloaded reports securely and limit access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AWS Security Hub CSPM (Cloud Security Posture Management)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/security-hub/cspm" rel="noopener noreferrer"&gt;AWS Security Hub CSPM&lt;/a&gt; A feature within Security Hub that continuously checks your AWS environment against best practices and compliance standards to identify misconfigurations and security gaps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Security Hub CSPM detects that RDS instances aren’t encrypted and that CloudTrail logging is disabled in a few accounts. Findings are sent to Slack via EventBridge for immediate action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable across all AWS accounts for unified visibility.&lt;/li&gt;
&lt;li&gt;Align CSPM rules with your company’s compliance framework.&lt;/li&gt;
&lt;li&gt;Use findings for automated remediation workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Included within Security Hub pricing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>cloud</category>
      <category>cloudsec</category>
    </item>
    <item>
      <title>How to create Root and Intermediate CA in AWS ACM Private CA to issue private certificates</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Mon, 06 May 2024 02:20:22 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-create-external-root-ca-and-intermediate-ca-in-aws-acm-pca-to-issue-private-certificates-56gm</link>
      <guid>https://dev.to/aws-builders/how-to-create-external-root-ca-and-intermediate-ca-in-aws-acm-pca-to-issue-private-certificates-56gm</guid>
      <description>&lt;p&gt;The purpose of this post is to show how to create an external root CA and an intermediate CA using AWS Private CA to be able to issue private certificates in AWS.&lt;/p&gt;

&lt;p&gt;To generate the certificates, you will need to use the &lt;code&gt;openssl&lt;/code&gt; tool, if it is not installed, use the following command to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install openssl
# or
sudo yum install openssl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a local environment for creating the certificate components:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ca
touch ca/root-openssl.cnf
touch ca/intermediate-openssl.cnf
touch ca/intermediate-request.csr
cd ca
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create external root certificate
&lt;/h2&gt;

&lt;p&gt;First, we must create the custom openssl configuration file to generate the certificate with the appropriate information and the extensions.&lt;/p&gt;

&lt;p&gt;The extensions will define the usefulness of the certificate, for more information about these extensions I recommend reading the &lt;a href="https://medium.com/r?url=https%3A%2F%2Fwww.openssl.org%2Fdocs%2Fman3.0%2Fman5%2Fx509v3_config.html" rel="noopener noreferrer"&gt;official openssl documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Fill the &lt;code&gt;root-openssl.cnf&lt;/code&gt; file with the content:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ req ]
distinguished_name              = req_distinguished_name
policy                          = policy_match
x509_extensions                 = v3_ca

[ policy_match ]
countryName                     = optional
stateOrProvinceName             = optional
organizationName                = optional
organizationalUnitName          = optional
commonName                      = supplied
emailAddress                    = optional

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = BR
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = State
localityName                    = Locality Name (eg, city)
localityName_default            = City
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = Organization
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = Organizational Unit
commonName                      = Common Name (eg, your name or your server hostname)
commonName_max                  = 64
emailAddress                    = Email Address
emailAddress_max                = 64

[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical,CA:true
keyUsage = critical,keyCertSign,digitalSignature,cRLSign
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Generate password to encrypt private key
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl rand -base64 32 &amp;gt; root-password-encrypted.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will generate 32 random characters to create a password that will be used to encrypt the private key.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Generate the encrypted private key
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -aes256 -out root-encrypted.key -passout file:root-password-encrypted.txt 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will generate a 4096-bit encrypted RSA private key using the AES256 encryption algorithm.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Generate the root CA certificate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -x509 -days 7300 -config root-openssl.cnf -key root-encrypted.key -passin file:root-password-encrypted.txt -out root-certificate.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will generate the self-signed root certificate based on the decrypted private key with an expiration time of 20 years (7300 days).&lt;/p&gt;

&lt;p&gt;When executing the command, you will be asked to fill in the certificate information such as CN, OU, etc.&lt;/p&gt;

&lt;p&gt;We can use the command below to view the certificate content in plain text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -in root-certificate.pem -text -noout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of this command will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            70:5a:46:4a:85:a6:20:51:4b:21:47:dc:1e:4a:d5:98:a9:c6:4b:d2
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = BR, ST = Minas Gerais, L = Belo Horizonte, O = Me, OU = Me, CN = Root CA
        Validity
            Not Before: May  5 19:05:30 2024 GMT
            Not After : Apr 30 19:05:30 2044 GMT
        Subject: C = BR, ST = Minas Gerais, L = Belo Horizonte, O = Me, OU = Me, CN = Root CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (4096 bit)
                Modulus:
                    00:c4:04:99:9e:f9:aa:13:02:b5:8e:19:49:44:77:
                    8c:4d:89:c6:0b:86:6b:6e:51:d7:0b:38:e2:69:aa:
                    f2:2c:ff:21:fd:b1:8b:f2:65:d9:0c:69:a2:f6:b0:
                    53:7c:92:9a:6d:ed:8a:3d:ce:6a:9d:2f:92:c4:17:
                    df:83:ef:a1:37:4d:c0:22:bd:85:55:7a:bd:81:a7:
                    02:31:50:08:49:ec:40:00:46:3c:16:ed:54:d8:9e:
                    db:9b:03:d8:75:e9:0d:54:81:da:de:98:87:aa:6c:
                    87:b8:fe:98:5f:d8:8d:22:a1:86:3d:03:ad:32:3d:
                    61:8e:bb:32:75:78:2a:e8:a7:4a:27:93:2b:09:de:
                    0a:f5:e2:4f:ae:d1:88:0e:11:42:82:da:31:ab:4c:
                    45:db:a6:60:c8:54:a0:6b:79:79:77:73:ad:e4:79:
                    7e:66:58:eb:a9:eb:9a:28:89:bf:85:76:93:42:53:
                    8c:f9:8b:d3:a5:88:aa:db:d9:ab:b6:82:76:f9:fd:
                    76:06:17:41:16:de:83:94:60:5c:d7:96:cd:87:76:
                    20:22:52:e1:6b:dc:f6:d1:b5:76:b3:01:03:7c:a0:
                    36:d4:d1:5b:e8:14:1a:60:e2:26:71:89:fc:aa:c8:
                    d9:25:66:0e:72:7b:5a:5d:02:86:11:05:44:0f:d2:
                    09:8e:51:34:0d:85:58:e2:e6:9e:ad:4e:04:1f:c0:
                    8b:0a:44:9a:b0:73:a2:0c:fc:1c:61:51:04:70:47:
                    7f:d2:d3:bd:b1:ce:8f:26:63:9c:63:8a:73:6a:e4:
                    7b:29:19:b6:1f:e1:3e:18:a0:a3:c9:75:46:06:f0:
                    06:85:e0:4d:87:03:84:b1:11:ba:c0:50:f9:ac:dd:
                    29:ff:c2:94:c5:59:02:61:37:c1:f2:0c:79:5d:ef:
                    96:7d:a8:ab:e3:c8:94:05:a1:e0:19:4a:3b:ad:37:
                    db:02:51:39:fa:0d:96:c3:88:d7:98:9c:6d:5e:62:
                    11:4f:44:58:26:1b:3c:5c:56:58:b4:f2:65:08:f4:
                    02:b8:11:44:76:01:62:b7:76:e7:fd:de:f4:3f:c9:
                    02:1f:e1:95:71:03:12:26:d0:78:23:0c:53:35:1d:
                    fd:9b:45:37:8e:46:96:f5:66:d4:a4:b5:36:79:d6:
                    50:0c:f1:e3:89:b4:79:32:09:5e:11:72:5c:65:34:
                    6c:9c:a3:45:8a:a7:04:6f:c7:88:d8:ac:93:ec:e9:
                    57:62:a3:9a:de:43:d9:72:63:40:c1:7b:dc:ba:cf:
                    2f:35:db:70:68:ed:1c:c6:78:89:8b:f4:29:da:e4:
                    79:4a:27:38:71:d8:61:4a:f9:dd:5f:8f:33:45:f4:
                    40:20:bd
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                61:51:2D:F8:F0:95:C5:FF:FE:96:A8:2C:E0:85:ED:58:E5:7F:0A:84
            X509v3 Authority Key Identifier:
                keyid:61:51:2D:F8:F0:95:C5:FF:FE:96:A8:2C:E0:85:ED:58:E5:7F:0A:84
X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         41:91:9e:85:54:bd:44:49:86:94:4c:d4:fb:8b:9e:c3:32:4f:
         6d:a3:8f:ea:e4:0f:b0:a2:97:24:56:64:3a:e6:99:15:2f:31:
         96:6c:ed:6f:cf:0a:8d:f8:1c:38:db:41:86:64:22:52:19:fd:
         3b:ff:22:92:37:f8:05:6e:0a:7c:f2:4b:ba:4c:5f:bf:5b:18:
         8f:f5:38:0c:22:49:15:de:17:99:e1:c5:69:3a:0f:d9:18:4d:
         c0:c5:6e:ff:32:35:df:e1:7e:c1:e7:0f:7f:b6:ed:a6:e2:0d:
         2f:cd:29:65:14:94:3d:90:79:e5:a7:3e:93:a6:d4:92:2a:b6:
         62:9f:41:20:ed:23:80:28:3d:80:cd:d4:47:bd:06:d3:6e:35:
         c9:28:6e:21:87:c7:72:39:c4:1c:66:fa:21:c2:73:f6:dd:ba:
         16:99:84:11:fb:91:f0:40:17:38:5a:24:c1:d2:2d:8d:be:76:
         34:05:95:f0:f3:bf:b2:5b:26:05:d1:28:5f:b8:e2:cb:db:d7:
         79:29:fe:8e:c5:4e:ac:97:55:f0:fd:37:42:f3:f0:23:27:f9:
         24:b4:92:f0:d0:23:63:10:52:82:55:61:fe:7a:c4:5f:5b:a8:
         7c:88:16:e2:8e:f1:72:bf:56:8b:23:c4:93:5b:3b:4b:d5:e9:
         e1:f4:bb:26:d4:2c:32:7c:f7:6a:a9:f3:42:21:a3:f4:5b:d3:
         f1:59:74:67:13:59:e6:81:3c:88:a2:2a:3a:25:b3:df:b2:b9:
         fd:b3:95:36:f4:18:bf:a1:51:b6:1d:c8:03:cc:a2:e6:2b:99:
         bb:36:68:48:88:96:31:f0:db:7f:f0:48:57:da:bc:dd:f4:f6:
         53:1b:57:7a:5f:16:ab:1b:f5:ff:a0:96:30:5f:8d:57:b5:b0:
         7c:f2:a2:40:27:6d:e6:20:5f:13:79:3c:5b:ac:5d:78:40:59:
         24:e2:91:5f:ac:e1:f2:c0:b7:87:b7:d0:66:78:06:6e:1b:77:
         b3:64:2d:62:14:e1:ec:cf:c3:2a:cb:38:08:87:04:11:ca:03:
         e6:a8:e1:4e:c4:13:ad:9b:ed:15:80:58:44:81:50:17:cf:ae:
         84:32:0c:b3:fc:89:93:db:9c:a1:56:7c:a0:5a:f9:37:7e:a0:
         81:dd:48:b4:a4:40:25:95:17:f3:00:0f:72:4d:9f:ca:9e:e0:
         c0:a1:d4:58:67:21:11:29:4c:97:0d:c6:38:db:c5:f8:80:98:
         1b:77:12:7c:7e:0c:bc:cc:11:d7:79:7e:45:d5:69:ae:5c:6d:
         a6:8a:a9:6c:c2:22:90:0d:74:a4:c5:af:56:72:cd:46:38:40:
         32:a9:05:29:5b:28:b9:fd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create Intermediate Certificate in AWS Private CA
&lt;/h2&gt;

&lt;p&gt;Now that we have our external root CA, the idea is to use it to sign the intermediate (subordinate) CA that we will create in AWS Private CA, this intermediate CA will be responsible for issuing the certificates for end use.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt;: Creating a CA on AWS has a cost of 400 dollars per month, but for the first CA the cost is minimal in the first month.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: The CA's private key is only stored in AWS, which is a security advantage as there is no risk of it being leaked and having to be revoked, on the other hand there is no way to export it .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To generate an intermediate CA, you must first generate your certificate signing request (CSR) so that it can be signed by the root CA.&lt;/p&gt;

&lt;p&gt;In AWS Private CA we select the subordinate type and fill in the certificate information, just as we did to generate the root CA, we normally fill in the same information for both with the exception of the &lt;em&gt;Common Name&lt;/em&gt; (CN) field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkeiajugfcdfezoo1fkr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkeiajugfcdfezoo1fkr.jpeg" alt="Create subordinate CA" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, we must select the type of private key algorithm (RSA or ECDSA) and optionally the certificate revocation configuration via CRL or OCSP.&lt;/p&gt;

&lt;p&gt;Once this is done, it will generate a new arn for this AWS resource and will be in &lt;em&gt;Pending Certificate&lt;/em&gt; status, because the request to generate the certificate (CSR) has been created but has not yet been signed by a root CA to issue the certificate for this intermediate CA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6hyu1skjqcd60b54s0a.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6hyu1skjqcd60b54s0a.jpeg" alt="Private CA created with status pending for installation" width="800" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To sign the CSR with our external root, we must select the resource and go to the &lt;em&gt;"Install CA certificate"&lt;/em&gt; option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr2h58arb3ztf1zbglo0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr2h58arb3ztf1zbglo0.jpeg" alt="Install CA — sign intermediate CA with root CA" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We then select whether this intermediate CA will be signed by a CA that already exists in the AWS PCA or whether it will be signed by an external CA, in our case it will be an external CA.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zwu9nuzoukcnrhq74jf.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zwu9nuzoukcnrhq74jf.jpeg" alt="Issue the subordinate CA with the external root CA" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AWS will make a certificate signing request (CSR) available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ob059a3vj9a1j959i5u.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ob059a3vj9a1j959i5u.jpeg" alt="CA CSR issued by AWS" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Copy the CSR content provided by AWS to the &lt;code&gt;intermediate-request.csr&lt;/code&gt; file
&lt;/h4&gt;

&lt;h4&gt;
  
  
  2. Fill the &lt;code&gt;intermediate-openssl.cnf&lt;/code&gt; file with the following content:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ intermediate_ca_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
basicConstraints = critical,CA:true,pathlen:0
keyUsage = critical,keyCertSign,digitalSignature,cRLSign
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Generate the intermediate CA certificate
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -req -days 3650 -extfile intermediate-openssl.cnf -extensions intermediate_ca_ext -in intermediate-request.csr -CA root-certificate.pem -CAkey root-encrypted.key -passin file:root-password-encrypted.txt -CAcreateserial -out intermediate-certificate.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To issue the certificate, we are based on the signature request (CSR) information made available by AWS &lt;code&gt;intermediate-request.csr&lt;/code&gt; signed by the root CA &lt;code&gt;root-certificate.pem&lt;/code&gt; and its encrypted private key &lt;code&gt;root-encrypted.key&lt;/code&gt; along with the password to decrypt it &lt;code&gt;root-password-encrypted.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We also pass the extension settings for this intermediate certificate based on the &lt;code&gt;intermediate_ca_ext&lt;/code&gt; profile in the &lt;code&gt;intermediate-openssl.cnf&lt;/code&gt; file, in addition to the number of days that the certificate will be valid, in this case 10 years (3650 days).&lt;/p&gt;

&lt;p&gt;Also set the random serial number creation using the &lt;code&gt;-CAcreateserial&lt;/code&gt; argument and thus generate the intermediate CA certificate &lt;code&gt;intermediate-certificate.pem&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the certificate generated, simply import the respective fields directly into AWS Private CA:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certificate body: Certificate of the intermediate CA  &lt;code&gt;intermediate-certificate.pem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Certificate chain: Root CA certificate &lt;code&gt;root-certificate.pem&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F072qyyubamuqhcruat8t.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F072qyyubamuqhcruat8t.jpeg" alt="Import the certificate body and chain" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the certificates imported, select the &lt;em&gt;"Install CA"&lt;/em&gt; option.&lt;/p&gt;

&lt;p&gt;This way we will have a certification authority (CA) chain to issue private certificates on AWS via ACM.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>acm</category>
      <category>ca</category>
      <category>certificate</category>
    </item>
    <item>
      <title>How to restrict default access to KMS via key policy with Terraform</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Sun, 31 Mar 2024 23:49:59 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-with-terraform-3lc1</link>
      <guid>https://dev.to/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-with-terraform-3lc1</guid>
      <description>&lt;p&gt;The objective of this post is to implement KMS key access security for AWS Identity and Access Management (IAM) identities by changing the default policy when provisioning the resource with Terraform.&lt;/p&gt;

&lt;p&gt;This is a practical example, so I first recommend recommend read &lt;a href="https://dev.to/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-28gc"&gt;this post&lt;/a&gt; to better understand the objective of restricted key policy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This post demonstrates the AWS account ID  &lt;code&gt;123456789012&lt;/code&gt; with existing role named &lt;code&gt;TERRAFORM&lt;/code&gt;, &lt;code&gt;ADMIN&lt;/code&gt; and &lt;code&gt;ANALYST&lt;/code&gt;. These values must be replaced for your environment.&lt;/p&gt;

&lt;p&gt;The default KMS key policy contains the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable IAM User Permissions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default KMS policy allow caller's account to use IAM policy to control key access.&lt;/p&gt;

&lt;p&gt;The Effect and Principal elements do not refer to the AWS root user account. Instead, it allows any principal in AWS account &lt;code&gt;123456789012&lt;/code&gt; to have root access to the KMS key as long as you have attached the required permissions to the IAM entity.&lt;/p&gt;

&lt;p&gt;The created terraform blueprint will come with the following custom policy by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable root access and prevent permission delegation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"aws:PrincipalType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Account"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow access for key administrators"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/TERRAFORM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ADMIN"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Create*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Enable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Put*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Update*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Revoke*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Disable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Delete*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:TagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:UntagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:ScheduleKeyDeletion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:CancelKeyDeletion"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable read access to all identities"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key policy allows the following permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First statement&lt;/strong&gt;: The AWS root user account has full access to the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second statement&lt;/strong&gt;: The principals role &lt;code&gt;ADMIN&lt;/code&gt; and &lt;code&gt;TERRAFORM&lt;/code&gt; has access to perform management operations on the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third statement&lt;/strong&gt; All account principals are able to read the key.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Terraform restrict KMS blueprint
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;versions.tf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Define Terraform versions and providers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.5"&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 5.0.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;code&gt;main.tf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Use the AWS provider in a region and create the KMS resource with your configuration parameters including your policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_kms_key"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Restricted kms key policy example"&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_iam_policy_document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;restricted_key_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;code&gt;variables.tf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines the variable that will be responsible for the value of the new desired policy to be attached to the KMS policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="nx"&gt;key_policy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"key policy"&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;sid&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;effect&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;actions&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;resources&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;principals&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
      &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})))&lt;/span&gt;
    &lt;span class="nx"&gt;conditions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})))&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;code&gt;policy.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Create a rule with the new default policy based on the current account id and merge it with the custom policy passed by variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_caller_identity"&lt;/span&gt; &lt;span class="s2"&gt;"current"&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;aws_account_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_caller_identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account_id&lt;/span&gt;
  &lt;span class="c1"&gt;# Default key policy to restrict AWS access&lt;/span&gt;
  &lt;span class="nx"&gt;default_key_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sid&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Enable root access and prevent permission delegation"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;principals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS"&lt;/span&gt;
          &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_account_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;actions&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;conditions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;test&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;
          &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aws:PrincipalType"&lt;/span&gt;
          &lt;span class="nx"&gt;values&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Account"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sid&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow access for key administrators"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;principals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS"&lt;/span&gt;
          &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"arn:aws:iam::${local.aws_account_id}:role/TERRAFORM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"arn:aws:iam::${local.aws_account_id}:role/ADMIN"&lt;/span&gt;
          &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;actions&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Create*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Enable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Put*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Update*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Revoke*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Disable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Delete*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:TagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:UntagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:ScheduleKeyDeletion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:CancelKeyDeletion"&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sid&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Enable read access to all identities"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;principals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS"&lt;/span&gt;
          &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_account_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Merge the default key policy with the new key policy&lt;/span&gt;
&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_policy_document"&lt;/span&gt; &lt;span class="s2"&gt;"restricted_key_policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;"statement"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;default_key_policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key_policy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sid&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sid&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;effect&lt;/span&gt;
      &lt;span class="nx"&gt;actions&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resources&lt;/span&gt;

      &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;"principals"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;principals&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;
          &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;principals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;identifiers&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nx"&gt;dynamic&lt;/span&gt; &lt;span class="s2"&gt;"condition"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="err"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conditions&lt;/span&gt;
        &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;test&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;
          &lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt;
          &lt;span class="nx"&gt;values&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. &lt;code&gt;outputs.tf&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines the output of the kms arn value after its creation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="nx"&gt;arn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_kms_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ARN KMS key"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. &lt;code&gt;terraform.tfvars&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Enter a custom policy for the purpose of creating the KMS, in this case I will create one just to allow the use of actions for a specific role.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;key_policy&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sid&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow use of the key"&lt;/span&gt;
      &lt;span class="nx"&gt;effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
      &lt;span class="nx"&gt;principals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS"&lt;/span&gt;
          &lt;span class="nx"&gt;identifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ANALYST"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;actions&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Encrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:ReEncrypt*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:GenerateDataKey*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"kms:DescribeKey"&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;resources&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After apply, as a result you will always have a restricted KMS with the possibility of customizing it by changing the value of the &lt;code&gt;key_policy&lt;/code&gt; variable, making it not only a secure blueprint but also scalable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/almeida-matheus/tf-security-enforcements/tree/master/aws/kms-policy" rel="noopener noreferrer"&gt;Check out the full code on GitHub!&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kms</category>
      <category>terraform</category>
      <category>security</category>
    </item>
    <item>
      <title>How to restrict default access to KMS via key policy</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Sun, 31 Mar 2024 23:49:31 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-28gc</link>
      <guid>https://dev.to/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-28gc</guid>
      <description>&lt;h2&gt;
  
  
  About AWS Key Management Service
&lt;/h2&gt;

&lt;p&gt;AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and control the cryptographic keys that are used to protect your data.&lt;/p&gt;

&lt;p&gt;The KMS key policy allows IAM identities in the account to access the KMS key with IAM permissions.&lt;/p&gt;

&lt;p&gt;The objective of this article is to implement secure of KMS key from access by AWS Identity and Access Management (IAM) identities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This article demonstrates the AWS account ID &lt;code&gt;123456789012&lt;/code&gt; with existing role named &lt;code&gt;TERRAFORM&lt;/code&gt;, &lt;code&gt;ADMIN&lt;/code&gt; and &lt;code&gt;ANALYST&lt;/code&gt;. These values must be replaced for your environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The default KMS Authorization behaviour
&lt;/h2&gt;

&lt;p&gt;The default KMS key policy contains the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable IAM User Permissions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default KMS policy allow caller's account to use IAM policy to control key access.&lt;/p&gt;

&lt;p&gt;The Effect and Principal elements do not refer to the AWS root user account. Instead, it allows any principal in AWS account &lt;code&gt;123456789012&lt;/code&gt; to have root access to the KMS key as long as you have attached the required permissions to the IAM entity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implement secure KMS policy
&lt;/h2&gt;

&lt;p&gt;Example of restricted key policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable root access and prevent permission delegation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"StringEquals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"aws:PrincipalType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Account"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow access for key administrators"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/TERRAFORM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ADMIN"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Create*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Enable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Put*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Update*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Revoke*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Disable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Delete*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:TagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:UntagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:ScheduleKeyDeletion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:CancelKeyDeletion"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Enable read access to all identities"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key policy allows the following permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First statement&lt;/strong&gt;: The AWS root user account has full access to the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Second statement&lt;/strong&gt;: The principals role &lt;code&gt;ADMIN&lt;/code&gt; and &lt;code&gt;TERRAFORM&lt;/code&gt; has access to perform management operations on the key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third statement&lt;/strong&gt; All account principals are able to read the key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way we can ensure that the root user account manages the key and prevents IAM entities from accessing the KMS key.&lt;/p&gt;

&lt;p&gt;You can also allow IAM users or roles to use the key for cryptographic operations and with other AWS services by appending other statements like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow analyst role use the key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AWS"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ANALYST"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Encrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:ReEncrypt*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:GenerateDataKey*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:DescribeKey"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow sms service use the key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Principal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"Service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sns.amazonaws.com"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:GenerateDataKey*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if the KMS is configured in this way, its access will be restricted and only those identities directly specified in the key policy will have access.&lt;/p&gt;

&lt;p&gt;Check out the completed code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Version"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"Statement"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Sid"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Enable root access and prevent permission delegation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Effect"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Principal"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"AWS"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"Action"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"kms:*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Resource"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Condition"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"aws:PrincipalType"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Account"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Sid"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow access for key administrators"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Effect"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Principal"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"AWS"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/TERRAFORM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ADMIN"&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"Action"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Create*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Enable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Put*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Update*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Revoke*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Disable*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Delete*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:TagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:UntagResource"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:ScheduleKeyDeletion"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:CancelKeyDeletion"&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"Resource"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Sid"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Enable read access to all identities"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Effect"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Principal"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"AWS"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"Action"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:List*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Get*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Describe*"&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"Resource"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Sid"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow use of the key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Effect"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"Principal"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"AWS"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"arn:aws:iam::123456789012:role/ANALYST"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s2"&gt;"Action"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:ReEncrypt*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:GenerateDataKey*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Encrypt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:DescribeKey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"kms:Decrypt"&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"Resource"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>kms</category>
      <category>security</category>
    </item>
    <item>
      <title>How to track Cognito Identity Pool IAM roles API calls via Athena</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Wed, 21 Feb 2024 02:17:32 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-track-cognito-identity-pool-iam-access-roles-api-calls-via-athena-32eo</link>
      <guid>https://dev.to/aws-builders/how-to-track-cognito-identity-pool-iam-access-roles-api-calls-via-athena-32eo</guid>
      <description>&lt;h2&gt;
  
  
  About Cloudtrail
&lt;/h2&gt;

&lt;p&gt;AWS CloudTrail is a service that records AWS API calls and events for AWS accounts. This service can save logs as JSON text files in compressed gzip format (*.json.gzip) in S3 Bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Athena
&lt;/h2&gt;

&lt;p&gt;AWS Athena is an interactive analytics service for large-scale data analysis, offering users the ability to perform SQL queries on data stored in S3 Bucket quickly, flexibly, and cost-effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  How these services work together
&lt;/h2&gt;

&lt;p&gt;Through AWS CloudTrail we can monitor and audit all activities carried out in your AWS account via Athena&lt;/p&gt;

&lt;p&gt;The purpose of the article is to demonstrate a way to perform Athena SQL query to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if the Cognito Identity Pool is being used&lt;/li&gt;
&lt;li&gt;Check which API calls to AWS are being made from temporary cognito IAM roles credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-create-a-trail-using-the-console-first-time.html" rel="noopener noreferrer"&gt;Create a trail&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/athena/latest/ug/getting-started.html#step-1-create-a-database" rel="noopener noreferrer"&gt;Create a Athena database and configure location query result&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run a Athena query to create table.&lt;/li&gt;
&lt;li&gt;Run a Athena query to obtain the trail logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Athena Queries
&lt;/h2&gt;

&lt;p&gt;To track Cognito roles API calls, we will use the table creation query from the &lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/creating-an-organizational-trail-in-the-console.html" rel="noopener noreferrer"&gt;official AWS documentation&lt;/a&gt; with an update.&lt;/p&gt;

&lt;p&gt;To be able to query the Cognito-role event you must change the CloudTrail table schema so that the &lt;code&gt;webIdFederationData&lt;/code&gt; column has the following definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;webIdFederationData: STRUCT&amp;lt;
                federatedProvider: STRING,
                attributes: map&amp;lt;string,string&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example Athena query to create table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE EXTERNAL TABLE cloudtrail_logs_pp(
    eventVersion STRING,
    userIdentity STRUCT&amp;lt;
        type: STRING,
        principalId: STRING,
        arn: STRING,
        accountId: STRING,
        invokedBy: STRING,
        accessKeyId: STRING,
        userName: STRING,
        sessionContext: STRUCT&amp;lt;
            attributes: STRUCT&amp;lt;
                mfaAuthenticated: STRING,
                creationDate: STRING&amp;gt;,
            sessionIssuer: STRUCT&amp;lt;
                type: STRING,
                principalId: STRING,
                arn: STRING,
                accountId: STRING,
                userName: STRING&amp;gt;,
            ec2RoleDelivery:string,
            webIdFederationData:map&amp;lt;string,string&amp;gt;
        &amp;gt;
    &amp;gt;,
    eventTime STRING,
    eventSource STRING,
    eventName STRING,
    awsRegion STRING,
    sourceIpAddress STRING,
    userAgent STRING,
    errorCode STRING,
    errorMessage STRING,
    requestparameters STRING,
    responseelements STRING,
    additionaleventdata STRING,
    requestId STRING,
    eventId STRING,
    readOnly STRING,
    resources ARRAY&amp;lt;STRUCT&amp;lt;
        arn: STRING,
        accountId: STRING,
        type: STRING&amp;gt;&amp;gt;,
    eventType STRING,
    apiVersion STRING,
    recipientAccountId STRING,
    serviceEventDetails STRING,
    sharedEventID STRING,
    vpcendpointid STRING,
    eventCategory STRING,
    tlsDetails struct&amp;lt;
        tlsVersion:string,
        cipherSuite:string,
        clientProvidedHostHeader:string&amp;gt;
  )
PARTITIONED BY (
   `timestamp` string)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://bucket-trail/AWSLogs/account-id/CloudTrail/aws-region'
TBLPROPERTIES (
  'projection.enabled'='true', 
  'projection.timestamp.format'='yyyy/MM/dd', 
  'projection.timestamp.interval'='1', 
  'projection.timestamp.interval.unit'='DAYS', 
  'projection.timestamp.range'='2020/01/01,NOW', 
  'projection.timestamp.type'='date', 
  'storage.location.template'='s3://bucket-trail/AWSLogs/account-id/CloudTrail/aws-region/${timestamp}')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Values that should be overridden for your environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LOCATION&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucket-trail&lt;/code&gt;: Name of the S3 bucket where the trail log is saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;012345678912&lt;/code&gt;: AWS Account ID.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;us-east-1&lt;/code&gt;: AWS region.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;projection.timestamp.range&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'2024/02/01,NOW'&lt;/code&gt;: Datetime range to track the trail logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;storage.location.template&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucket-trail&lt;/code&gt;: Name of the S3 bucket where the trail log is saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;012345678912&lt;/code&gt;: AWS Account ID.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;us-east-1&lt;/code&gt;: AWS region.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Run a Athena query to obtain the trail logs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
 useridentity.arn,
 eventname,
 sourceipaddress,
 eventtime
FROM cloudtrail_logs
WHERE userIdentity.sessionContext.sessionIssuer.arn = 'arn:aws:iam::123456789012:role/ROLE-UNAUTHENTICATED'
LIMIT 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Values that should be overridden for your environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;WHERE userIdentity.sessionContext.sessionIssuer.arn = 'arn:aws:iam::123456789012:role/ROLE-UNAUTHENTICATED'
&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'arn:aws:iam::123456789012:role/ROLE-UNAUTHENTICATED'&lt;/code&gt;: Cognito Identity Pool role arn.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>athena</category>
      <category>cloudtrail</category>
      <category>cognito</category>
    </item>
    <item>
      <title>How to track Cloudtrail API calls from all Organizations AWS accounts using Athena</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Wed, 21 Feb 2024 02:17:21 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-track-cloudtrail-api-calls-from-all-organizations-aws-accounts-using-athena-1dk4</link>
      <guid>https://dev.to/aws-builders/how-to-track-cloudtrail-api-calls-from-all-organizations-aws-accounts-using-athena-1dk4</guid>
      <description>&lt;h2&gt;
  
  
  About Cloudtrail
&lt;/h2&gt;

&lt;p&gt;AWS CloudTrail is a service that records AWS API calls and events for AWS accounts. This service can save logs as JSON text files in compressed gzip format (*.json.gzip) in S3 Bucket.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Athena
&lt;/h2&gt;

&lt;p&gt;AWS Athena is an interactive analytics service for large-scale data analysis, offering users the ability to perform SQL queries on data stored in S3 Bucket quickly, flexibly, and cost-effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Organizations
&lt;/h2&gt;

&lt;p&gt;AWS Organizations is a service that allows companies to manage multiple AWS accounts in a single hierarchical structure. It consolidates billing for these accounts, also helps automate account and resource management, as well as the enforcement of security and compliance policies across all accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  How these services work together
&lt;/h2&gt;

&lt;p&gt;By integrating AWS Organizations with AWS CloudTrail, we can monitor and audit all activities performed in your AWS accounts via Athena.&lt;/p&gt;

&lt;p&gt;The purpose of the article is to demonstrate a way to perform SQL query in athena to search for information from all AWS accounts and regions of an Organizations, instead of performing queries by region and specific AWS account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: queries will have lower performance due to the larger amount of data, but depending on the occasion this may be useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/awscloudtrail/latest/userguide/creating-an-organizational-trail-in-the-console.html" rel="noopener noreferrer"&gt;Create a Organization trail&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.aws.amazon.com/athena/latest/ug/getting-started.html#step-1-create-a-database" rel="noopener noreferrer"&gt;Create a Athena database and configure location query result&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Run a Athena query to create table.&lt;/li&gt;
&lt;li&gt;Run a Athena query to obtain the trail logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3 - Run a Athena query to create table
&lt;/h3&gt;

&lt;p&gt;Values that should be overridden for your environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LOCATION&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucket-trail&lt;/code&gt;: Name of the S3 bucket where the trail log is saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o-123456789&lt;/code&gt;: Organization ID.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;storage.location.template&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bucket-trail&lt;/code&gt;: Name of the S3 bucket where the trail log is saved.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o-123456789&lt;/code&gt;: Organization ID.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;projection.timestamp.range&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'2024/02/01,NOW'&lt;/code&gt;: Datetime range to track the trail logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;projection.accountid.values&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'012345678912,219876543210'&lt;/code&gt;: AWS accounts IDs to track the trail logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;projection.region.values&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'us-east-1,sa-east-1'&lt;/code&gt;: AWS regions to track the trail logs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example Athena query to create table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE EXTERNAL TABLE cloudtrail_logs_all_accounts(
  eventVersion STRING,
  userIdentity STRUCT&amp;lt;
    type: STRING,
    principalId: STRING,
    arn: STRING,
    accountId: STRING,
    invokedBy: STRING,
    accessKeyId: STRING,
    userName: STRING,
    sessionContext: STRUCT&amp;lt;
      attributes: STRUCT&amp;lt;
        mfaAuthenticated: STRING,
        creationDate: STRING&amp;gt;,
      sessionIssuer: STRUCT&amp;lt;
        type: STRING,
        principalId: STRING,
        arn: STRING,
        accountId: STRING,
        userName: STRING&amp;gt;,
      ec2RoleDelivery:string,
      webIdFederationData: STRUCT&amp;lt;
        federatedProvider: STRING,
        attributes: map&amp;lt;string,string&amp;gt;&amp;gt;
    &amp;gt;
  &amp;gt;,
  eventTime STRING,
  eventSource STRING,
  eventName STRING,
  awsRegion STRING,
  sourceIpAddress STRING,
  userAgent STRING,
  errorCode STRING,
  errorMessage STRING,
  requestparameters STRING,
  responseelements STRING,
  additionaleventdata STRING,
  requestId STRING,
  eventId STRING,
  readOnly STRING,
  resources ARRAY&amp;lt;STRUCT&amp;lt;
    arn: STRING,
    accountId: STRING,
    type: STRING&amp;gt;&amp;gt;,
  eventType STRING,
  apiVersion STRING,
  recipientAccountId STRING,
  serviceEventDetails STRING,
  sharedEventID STRING,
  vpcendpointid STRING,
  tlsDetails struct&amp;lt;
    tlsVersion:string,
    cipherSuite:string,
    clientProvidedHostHeader:string&amp;gt;
)
PARTITIONED BY ( 
  `timestamp` string, 
  `region` string, 
  `accountid` string)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
  's3://bucket-trail/AWSLogs/o-123456789'
TBLPROPERTIES (
  'storage.location.template'='s3://bucket-trail/AWSLogs/o-123456789/${accountid}/CloudTrail/${region}/${timestamp}', 
  'projection.enabled'='true', 
  'projection.timestamp.type'='date', 
  'projection.timestamp.format'='yyyy/MM/dd', 
  'projection.timestamp.interval'='1', 
  'projection.timestamp.interval.unit'='DAYS', 
  'projection.timestamp.range'='2024/02/01,NOW', 
  'projection.accountid.type'='enum', 
  'projection.accountid.values'='012345678912,219876543210', 
  'projection.region.type'='enum', 
  'projection.region.values'='us-east-1,sa-east-1'
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run a Athena query to obtain the trail logs
&lt;/h3&gt;

&lt;p&gt;Values that should be overridden for your environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FROM cloudtrail_logs&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cloudtrail_logs&lt;/code&gt;: Name of the table created above.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;WHERE userIdentity.sessionContext.sessionIssuer.arn = 'arn:aws:iam::012345678912:role/ROLE-NAME'&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;'arn:aws:iam::012345678912:role/ROLE-NAME'&lt;/code&gt;: Identity arn to track your trail log, be it role or user.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example Athena query to track identity trail logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cloudtrail_logs
WHERE userIdentity.sessionContext.sessionIssuer.arn = 'arn:aws:iam::012345678912:role/ROLE-NAME'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IAM Policy example required to execute the above queries after configuring the log trail and the Athena database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AthenaRunQuery",
            "Effect": "Allow",
            "Action": [
                "athena:StartQueryExecution",
                "athena:GetQueryExecution",
                "athena:GetQueryResults",
                "athena:StopQueryExecution"
            ],
            "Resource": [
                "arn:aws:athena:us-east-1:012345678912:workgroup/*",
                "arn:aws:athena:us-east-1:012345678912:queryExecution/*"
            ]
        },
        {
            "Sid": "S3BucketLoggingAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload",
                "s3:PutObject*"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-query-result",
                "arn:aws:s3:::bucket-query-result/*"
            ]
        },
        {
            "Sid": "S3BucketQueryAccess",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::bucket-trail",
                "arn:aws:s3:::bucket-trail/*"
            ]
        },
        {
            "Sid": "GlueWrite",
            "Effect": "Allow",
            "Action": [
                "glue:CreateTable",
                "glue:DeleteTable",
                "glue:BatchCreatePartition"
            ],
            "Resource": "arn:aws:glue:us-east-1:012345678912:*"
        },
        {
            "Sid": "GlueRead",
            "Action": [
                "glue:GetTable*",
                "glue:List*",
                "glue:GetPartition*",
                "glue:GetDatabase"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:glue:us-east-1:012345678912:*"
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>aws</category>
      <category>athena</category>
      <category>cloudtrail</category>
      <category>sql</category>
    </item>
    <item>
      <title>Automated way to restrict all inbound and outbound rules from AWS default security groups</title>
      <dc:creator>Matheus Almeida Costa</dc:creator>
      <pubDate>Fri, 09 Feb 2024 21:07:35 +0000</pubDate>
      <link>https://dev.to/aws-builders/automated-way-to-restrict-all-inbound-and-outbound-rules-from-aws-default-security-groups-22o1</link>
      <guid>https://dev.to/aws-builders/automated-way-to-restrict-all-inbound-and-outbound-rules-from-aws-default-security-groups-22o1</guid>
      <description>&lt;p&gt;For each VPC created in AWS, a default security group is always automatically created, in this security group there is an inbound rule that allows access to all protocols and ports of the security group itself as source and it also has an outbound rule that allows access to all protocols and ports to the internet as source.&lt;/p&gt;

&lt;p&gt;Following good security practices, it is not recommended to use default security groups associated with AWS resources, but rather to create custom security groups with least privileges for these resources.&lt;/p&gt;

&lt;p&gt;The objective of this post is to present a script to delete all inbound and outbound rules from the default security groups of all VPCs and regions in an AWS account.&lt;/p&gt;

&lt;p&gt;This makes the use of default security groups useless and will reduce AWS compliance security alerts for default security group that does not restrict all traffic.&lt;/p&gt;

&lt;p&gt;It is important to remove the association of AWS resources with the default security group if used, to find out if it is being used by an AWS resource you can consult the network interfaces according to &lt;a href="https://repost.aws/knowledge-center/ec2-find-security-group-resources" rel="noopener noreferrer"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To run the code above you need to install &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;python 3&lt;/a&gt; with dependency &lt;a href="https://pypi.org/project/boto3/" rel="noopener noreferrer"&gt;boto3&lt;/a&gt; and configure your &lt;a href="https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html" rel="noopener noreferrer"&gt;AWS credentials&lt;/a&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note 1&lt;/strong&gt;: Default security groups always have the name "default" and it is not possible to create a security group with that same name, so there is no chance of deleting rules from other security groups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: In regions used in your AWS account, it may make sense to manually evaluate the update of the default security group via network interfaces, so in this case it is recommended to exclude the elements (regions) from the &lt;code&gt;regions&lt;/code&gt; variable array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 3&lt;/strong&gt;: This will not prevent more non-restricted default security groups from being created, to accomplish this you can add configuration parameters to your infrastructure as code, as &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_security_group" rel="noopener noreferrer"&gt;this terraform resource&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>boto3</category>
      <category>vpc</category>
    </item>
  </channel>
</rss>
