<?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>Forem: Matheus Almeida Costa</title>
    <description>The latest articles on Forem by Matheus Almeida Costa (@almeidamatheus).</description>
    <link>https://forem.com/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>Forem: Matheus Almeida Costa</title>
      <link>https://forem.com/almeidamatheus</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/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://forem.com/aws-builders/how-to-ensure-security-tool-connectivity-on-ec2-across-aws-accounts-with-automated-security-group-mbh</link>
      <guid>https://forem.com/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://forem.com/aws-builders/aws-security-services-overview-1ko8</link>
      <guid>https://forem.com/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 resumed reference guide 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 grouped by category, with a short scenario and a few practical notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity &amp;amp; Access Management&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;AWS Identity and Access Management (IAM)&lt;/li&gt;
&lt;li&gt;AWS IAM Access Analyzer&lt;/li&gt;
&lt;li&gt;AWS IAM Identity Center&lt;/li&gt;
&lt;li&gt;AWS Organizations&lt;/li&gt;
&lt;li&gt;AWS Resource Access Manager (RAM)&lt;/li&gt;
&lt;li&gt;Amazon Cognito&lt;/li&gt;
&lt;li&gt;AWS Directory Service&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Data Protection&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;AWS Secrets Manager&lt;/li&gt;
&lt;li&gt;AWS Private Certificate Authority (Private CA)&lt;/li&gt;
&lt;li&gt;AWS Certificate Manager (ACM)&lt;/li&gt;
&lt;li&gt;Amazon Macie&lt;/li&gt;
&lt;li&gt;AWS Key Management Service (KMS)&lt;/li&gt;
&lt;li&gt;AWS CloudHSM&lt;/li&gt;
&lt;li&gt;AWS Payment Cryptography&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;AWS WAF&lt;/li&gt;
&lt;li&gt;AWS Shield&lt;/li&gt;
&lt;li&gt;AWS Network Firewall&lt;/li&gt;
&lt;li&gt;AWS Firewall Manager&lt;/li&gt;
&lt;li&gt;AWS Verified Access&lt;/li&gt;
&lt;li&gt;Amazon VPC Lattice&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;AWS CloudTrail&lt;/li&gt;
&lt;li&gt;Amazon GuardDuty&lt;/li&gt;
&lt;li&gt;AWS Security Hub&lt;/li&gt;
&lt;li&gt;Amazon Detective&lt;/li&gt;
&lt;li&gt;Amazon Inspector&lt;/li&gt;
&lt;li&gt;Amazon Security Lake&lt;/li&gt;
&lt;li&gt;AWS Security Incident Response&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Application Security&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;AWS Systems Manager&lt;/li&gt;
&lt;li&gt;AWS Signer&lt;/li&gt;
&lt;li&gt;AWS Security Agent&lt;/li&gt;
&lt;li&gt;Amazon Verified Permissions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;AWS Config&lt;/li&gt;
&lt;li&gt;AWS Audit Manager&lt;/li&gt;
&lt;li&gt;AWS Artifact&lt;/li&gt;
&lt;/ul&gt;


&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 an AWS account. It handles authentication (users, roles, federated identities) and authorization (policies) across 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 so developers can deploy Lambda functions only in non-production accounts. Each role uses scoped permissions, and developers assume the role with temporary credentials instead of relying on 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 least privilege. Only grant what's actually needed.&lt;/li&gt;
&lt;li&gt;Replace IAM users with roles and short-lived credentials wherever possible.&lt;/li&gt;
&lt;li&gt;Enforce MFA on every privileged identity.&lt;/li&gt;
&lt;li&gt;Run IAM Access Analyzer regularly to find unused permissions and external access. Since 2024 it also surfaces unused-access findings, which is useful for cleaning up over-permissive roles.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Free.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS IAM Access Analyzer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/iam/access-analyzer/" rel="noopener noreferrer"&gt;IAM Access Analyzer&lt;/a&gt; uses automated reasoning (what AWS calls "provable security") to find resources shared outside your trust boundary, identify unused permissions, and validate IAM policies before they ship. It runs across S3 buckets, IAM roles, KMS keys, Lambda functions, SQS queues, Secrets Manager, and others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A new feature ships with an S3 bucket policy that accidentally allows &lt;code&gt;s3:GetObject&lt;/code&gt; from any account. Access Analyzer flags it within minutes as an external access finding, and the team rolls back the policy before any data leaves the account.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable both an external access analyzer and an unused access analyzer at the organization level.&lt;/li&gt;
&lt;li&gt;Wire custom policy checks into CI/CD so policies that grant new access trigger an approval step before merge.&lt;/li&gt;
&lt;li&gt;Treat findings like security tickets, not informational logs. Archive intentional ones and resolve the rest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
External access analysis is free. Unused access analysis is per IAM role or user analyzed per month.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS IAM Identity Center
&lt;/h3&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; (formerly AWS SSO) is the recommended way to manage human access across multiple AWS accounts. It connects to identity providers like Okta, Entra ID, or Google Workspace and centralizes permission sets per account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company with 12 AWS accounts integrates Identity Center with Entra ID. Employees log in once with their corporate credentials and land on a portal that shows only the accounts and roles they're entitled to, mapped from their AD groups.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Assign access by group, not by individual user.&lt;/li&gt;
&lt;li&gt;Map directory groups to AWS accounts and permission sets.&lt;/li&gt;
&lt;li&gt;Enable MFA and reasonable session timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Free.&lt;/p&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; lets you centrally manage multiple AWS accounts as a single entity. It's where you set up Organizational Units (OUs), Service Control Policies (SCPs), and the more recent Resource Control Policies (RCPs) to define guardrails across the whole environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A platform team groups production accounts under a "Prod" OU and applies an SCP that blocks anyone (including admins) from disabling CloudTrail or operating outside approved regions. Even if a member account creates a role with &lt;code&gt;AdministratorAccess&lt;/code&gt;, the SCP still wins.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Use OUs to reflect environments or business units, not just teams.&lt;/li&gt;
&lt;li&gt;Combine SCPs (identity guardrails) with RCPs (resource-side guardrails) to build a data perimeter.&lt;/li&gt;
&lt;li&gt;Enable trusted access for services like CloudTrail, Config, and GuardDuty so they can be managed organization-wide.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Free.&lt;/p&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; shares AWS resources like subnets, Transit Gateways, or Route 53 Resolver rules across accounts inside an Organization, without duplicating infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A central network account owns the Transit Gateway and shares it through RAM with workload accounts. Each team works in its own VPC but uses shared connectivity, keeping the network footprint consistent.&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 what's needed, and only with the accounts that actually need it.&lt;/li&gt;
&lt;li&gt;Audit shares regularly. Old ones tend to outlive the projects that created them.&lt;/li&gt;
&lt;li&gt;Tag shared resources with an owner so accountability is clear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Free.&lt;/p&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 end-user applications. User pools manage sign-up and sign-in; identity pools issue temporary AWS credentials for federated users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A mobile app lets users sign in with Google or Apple ID. Cognito brokers the federation and hands back short-lived AWS credentials so the app can call backend APIs through API Gateway.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enforce a strong password policy and enable MFA.&lt;/li&gt;
&lt;li&gt;Use Cognito triggers (Lambda) when you need custom validation or extra checks at sign-up or sign-in.&lt;/li&gt;
&lt;li&gt;Keep tokens out of insecure storage on the client side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per monthly active user (MAU), with a free tier for the first 50,000 MAUs in most cases.&lt;/p&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 in AWS, or connects AWS resources to an existing on-prem AD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company migrates Windows workloads to EC2 and wants to keep the same group policies and authentication flow. AWS Managed Microsoft AD gives them a real AD domain in AWS, with a trust to the on-prem forest.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Pick Managed Microsoft AD when you need full AD features. AD Connector is enough if you only need to proxy authentication to on-prem.&lt;/li&gt;
&lt;li&gt;Keep domain admin accounts separate from day-to-day accounts.&lt;/li&gt;
&lt;li&gt;Send directory logs to CloudWatch for visibility into logins and policy changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per directory type and per hour.&lt;/p&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;Secrets Manager&lt;/a&gt; stores, rotates, and serves credentials, API keys, and other secrets, with native rotation support for RDS, Redshift, and DocumentDB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Instead of putting a database password in a Lambda environment variable, the function fetches it from Secrets Manager at runtime. A rotation Lambda swaps the password in RDS and updates the secret on a schedule, with no application changes required.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Turn on automatic rotation, especially for database credentials.&lt;/li&gt;
&lt;li&gt;Scope IAM access down to the specific secret ARN. Wildcards on &lt;code&gt;secretsmanager:GetSecretValue&lt;/code&gt; are a common mistake.&lt;/li&gt;
&lt;li&gt;Encrypt secrets with a customer-managed KMS key when you want full control over who can decrypt them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per secret per month, plus a small charge per 10,000 API calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Private Certificate Authority (Private 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 CA&lt;/a&gt; issues and manages private TLS certificates for internal services, IoT devices, and other workloads that don't need a publicly trusted CA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An internal platform issues short-lived certificates to microservices through Private CA, replacing long-lived self-signed certs scattered across containers.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Automate issuance and renewal. Manual cert management never scales.&lt;/li&gt;
&lt;li&gt;Keep certificate lifetimes short to reduce blast radius if a key leaks.&lt;/li&gt;
&lt;li&gt;Restrict who can issue certificates with IAM and CA-level permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Monthly fee per CA, plus a per-certificate fee that drops at higher volumes.&lt;/p&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;ACM&lt;/a&gt; provisions, deploys, and renews public and private TLS certificates for AWS-integrated services like CloudFront, ALB, and API Gateway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A site behind CloudFront gets a free public ACM certificate validated via DNS. Renewal happens automatically, with no calendar reminders and no expired-cert pages.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Prefer DNS validation for fully automated renewal.&lt;/li&gt;
&lt;li&gt;Use ACM for any AWS-integrated endpoint. Reach for Private CA only when you need certs outside that scope.&lt;/li&gt;
&lt;li&gt;Pair with WAF in front of CloudFront or ALB for layered protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Public certificates are free. Private certificates go through Private CA pricing.&lt;/p&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;Macie&lt;/a&gt; uses ML and pattern matching to find sensitive data (PII, credentials, financial data) sitting in S3, and flags buckets that look risky.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
After Macie runs on a data lake, it surfaces a few buckets containing customer PII that nobody had classified. The findings feed into Security Hub and trigger remediation through Config.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Schedule recurring jobs on the buckets that actually matter. Running it on everything gets expensive fast.&lt;/li&gt;
&lt;li&gt;Use managed data identifiers first, then add custom ones for company-specific patterns.&lt;/li&gt;
&lt;li&gt;Send findings to Security Hub so they live alongside everything else.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per GB classified and per object monitored.&lt;/p&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;KMS&lt;/a&gt; creates and manages cryptographic keys used by AWS services and applications, with everything logged in CloudTrail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A finance team encrypts S3 and RDS with customer-managed keys (CMKs). Key policies restrict decryption to specific roles, and CloudTrail captures every &lt;code&gt;Decrypt&lt;/code&gt; call for audit.&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 keys for sensitive data. AWS-managed keys are fine for low-risk workloads but offer less control.&lt;/li&gt;
&lt;li&gt;Enable automatic annual rotation.&lt;/li&gt;
&lt;li&gt;Be careful with key policies. Locking yourself out of a CMK is a real (and painful) failure mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per key per month, plus per API request.&lt;/p&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;CloudHSM&lt;/a&gt; gives you dedicated, FIPS 140-2 Level 3-validated Hardware Security Modules. Unlike KMS, the keys live in an HSM that only you control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A payments company processing card transactions needs full custody of the keys used for cryptographic operations. CloudHSM provides isolated HSMs in the customer's VPC, satisfying PCI DSS key-management requirements.&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 regulation or contracts require exclusive key control. Otherwise KMS is usually enough.&lt;/li&gt;
&lt;li&gt;Run an HSM cluster across multiple AZs for redundancy.&lt;/li&gt;
&lt;li&gt;Consider a KMS custom key store backed by CloudHSM if you need both ecosystems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Hourly per HSM instance.&lt;/p&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;Payment Cryptography&lt;/a&gt; provides managed cryptographic operations specifically for payment processing, including PIN translation, key exchange, and similar operations that traditionally required on-prem HSMs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A fintech replaces a legacy on-prem HSM setup with Payment Cryptography to handle PIN generation and key exchange with acquiring banks, while staying inside PCI PIN scope.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Pair with strict IAM conditions (e.g. source VPC, source IP) to limit who can call cryptographic operations.&lt;/li&gt;
&lt;li&gt;Rotate keys on a defined schedule and document it for audit.&lt;/li&gt;
&lt;li&gt;Keep CloudTrail logs of all operations as part of the compliance evidence chain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per active key and per cryptographic API call.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  AWS 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; is a layer-7 firewall that protects HTTP(S) endpoints from common exploits like SQL injection, XSS, and bad bots. It integrates with CloudFront, ALB, API Gateway, AppSync, and App Runner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
An API behind API Gateway is the front door for a retail app. WAF blocks requests with obvious injection patterns and rate-limits abusive clients before they reach the backend.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Start with AWS Managed Rule Groups (Core, Known Bad Inputs, OWASP-style sets) and tune from there.&lt;/li&gt;
&lt;li&gt;Add rate-based rules to slow down brute-force and credential stuffing.&lt;/li&gt;
&lt;li&gt;Send logs to CloudWatch, S3, or Kinesis Firehose so you can actually investigate when something is blocked, or when it isn't.&lt;/li&gt;
&lt;li&gt;Keep separate Web ACLs for staging and production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per Web ACL, per rule, and per million requests inspected.&lt;/p&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;Shield&lt;/a&gt; protects against DDoS attacks. Shield Standard is automatic and free; Shield Advanced adds higher-tier mitigations, cost protection, and access to the AWS Shield Response Team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A public API behind CloudFront sees a sudden traffic spike. Shield Standard absorbs the volumetric portion automatically. With Shield Advanced, the customer also gets detailed attack diagnostics and 24/7 escalation if mitigation needs human input.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable Shield Advanced for critical public-facing workloads where downtime has real financial impact.&lt;/li&gt;
&lt;li&gt;Always pair with WAF for application-layer attacks. Shield alone won't stop a slow HTTP flood.&lt;/li&gt;
&lt;li&gt;Run game days that simulate traffic surges so the team isn't learning the runbook during a real incident.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Standard: free. Advanced: monthly subscription per organization, plus data transfer.&lt;/p&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;Network Firewall&lt;/a&gt; is a managed stateful firewall and IPS for VPC traffic. It supports Suricata-compatible rules, so existing rule sets often port over with minimal changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A central inspection VPC sits behind a Transit Gateway. All east-west and egress traffic flows through Network Firewall, where the security team enforces domain allowlists and Suricata IDS rules.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Centralize the firewall in a shared inspection VPC rather than deploying per-VPC instances.&lt;/li&gt;
&lt;li&gt;Log everything to S3 or CloudWatch. Without logs, troubleshooting a blocked flow is guesswork.&lt;/li&gt;
&lt;li&gt;Use domain-based stateful rules for egress filtering. They're much easier to maintain than IP lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per firewall endpoint hour, plus per GB processed.&lt;/p&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;Firewall Manager&lt;/a&gt; centrally manages WAF, Shield Advanced, Network Firewall, and security group policies across all accounts in an Organization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A security team defines a baseline WAF rule set that every CloudFront distribution in the org must have. Firewall Manager applies it automatically to new distributions as they're created.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Pair with AWS Organizations for org-wide reach.&lt;/li&gt;
&lt;li&gt;Use resource tags to scope policies. For example, only enforce certain rules on resources tagged &lt;code&gt;env=prod&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Treat Firewall Manager policies like infrastructure-as-code: version them, review changes, and avoid clicking around in the console.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per policy per region per month.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Verified Access
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/verified-access/" rel="noopener noreferrer"&gt;AWS Verified Access&lt;/a&gt; provides VPN-less access to internal applications. Each request is evaluated against identity (via an IdP), device posture (via integrations with Jamf, CrowdStrike, Zscaler, and others), and policy context before access is granted, which makes it a practical building block for zero-trust architectures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company replaces its corporate VPN with Verified Access. An engineer accessing an internal Grafana dashboard is authenticated through Entra ID, has their device posture checked by CrowdStrike, and gets a short-lived session, with the whole evaluation logged for audit.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Define access policies per application instead of one broad policy. Sensitive apps get stricter device and identity requirements.&lt;/li&gt;
&lt;li&gt;Require both identity and device trust providers. Identity alone misses compromised endpoints.&lt;/li&gt;
&lt;li&gt;Send evaluation logs to S3 or OpenSearch so failed access attempts are visible during incident reviews.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per application per hour, plus per GB of data processed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon VPC Lattice
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/vpc/lattice/" rel="noopener noreferrer"&gt;VPC Lattice&lt;/a&gt; is an application networking service that connects services across VPCs and accounts without the usual peering or routing complexity. It includes IAM-based auth policies that gate service-to-service traffic, which is what makes it relevant in a security post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A microservices platform running across three accounts uses VPC Lattice to expose internal services. Auth policies require requests to come from a specific IAM role and carry a particular tag, blocking traffic from any other workload even if they're on the same network.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Treat VPC Lattice auth policies as part of your security model, not just networking config.&lt;/li&gt;
&lt;li&gt;Combine with Verified Access for the user-to-service hop. Lattice handles service-to-service.&lt;/li&gt;
&lt;li&gt;Share service networks through RAM rather than rebuilding per account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per service per hour, per request, and per GB processed.&lt;/p&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;CloudTrail&lt;/a&gt; records API calls and management events across an AWS account. It's the foundation for auditing, forensics, and most compliance work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Someone accidentally makes an S3 bucket public. CloudTrail captures the &lt;code&gt;PutBucketPolicy&lt;/code&gt; call, including the user identity, source IP, and timestamp, which is exactly what the security team needs to investigate and reverse it.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Set up an organization trail so every account is covered, including new ones.&lt;/li&gt;
&lt;li&gt;Send logs to a dedicated logging account with restricted access. Production teams shouldn't be able to delete their own audit trail.&lt;/li&gt;
&lt;li&gt;Turn on CloudTrail Insights for anomaly detection on API call patterns.&lt;/li&gt;
&lt;li&gt;Enable data events selectively. They're powerful but can get expensive on busy S3 buckets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
One management trail per region is free. Additional trails and data events are billed per 100,000 events.&lt;/p&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;GuardDuty&lt;/a&gt; is a managed threat detection service. It analyzes CloudTrail, VPC Flow Logs, DNS logs, EKS audit logs, S3 data events, RDS login activity, and EBS volumes for malware, using a mix of ML and threat intelligence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
GuardDuty raises a finding that an EC2 instance is talking to a known crypto-mining domain. An EventBridge rule triggers a Lambda that detaches the instance role, isolates the security group, and creates a snapshot for forensics.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable it organization-wide. Turning it on per-account is a recipe for blind spots.&lt;/li&gt;
&lt;li&gt;Enable the protection plans that match your stack (EKS, S3, RDS, Malware Protection, Lambda) rather than leaving them off by default.&lt;/li&gt;
&lt;li&gt;Suppress known-benign findings instead of ignoring the inbox.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Based on volume of logs analyzed and resources protected. Each protection plan adds its own usage charge.&lt;/p&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;Security Hub&lt;/a&gt; aggregates findings from GuardDuty, Inspector, Macie, IAM Access Analyzer, Config, and dozens of partner products into a single place. It's split into Security Hub CSPM (the posture-management piece) and the broader Security Hub experience that consolidates detection findings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A compliance lead enables the AWS Foundational Security Best Practices and CIS standards in Security Hub CSPM. The dashboard immediately surfaces unencrypted S3 buckets, missing CloudTrail trails, and overly permissive security groups across every account.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable the standards that match the company's compliance scope. Don't enable all of them and drown in noise.&lt;/li&gt;
&lt;li&gt;Use cross-account aggregation so one delegated administrator account holds the full picture.&lt;/li&gt;
&lt;li&gt;Set up automated remediation for the highest-frequency findings (public S3, unencrypted volumes, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per finding ingested and per compliance check evaluated.&lt;/p&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;Detective&lt;/a&gt; automatically pulls in CloudTrail, VPC Flow Logs, GuardDuty findings, and EKS audit logs, then builds a behavior graph you can pivot through during an investigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A GuardDuty finding suggests a compromised IAM access key. Detective shows the affected role's activity over the past weeks, the resources it touched, and other identities behaving similarly, all without writing custom queries.&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 the same accounts where GuardDuty is on. The two pair naturally.&lt;/li&gt;
&lt;li&gt;Treat it as an investigation tool, not a real-time alerting system.&lt;/li&gt;
&lt;li&gt;Default 12-month data retention is usually worth keeping for incident postmortems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per GB of data ingested per month.&lt;/p&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;Inspector&lt;/a&gt; continuously scans EC2 instances, container images in ECR, and Lambda functions for known CVEs and unintended network exposure. Findings are scored using a contextual risk model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
Inspector flags an outdated OpenSSL package on a running EC2 instance. The finding flows into Security Hub, opens a ticket in Jira, and gets patched in the next deployment cycle.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable it across the organization so new resources are covered automatically.&lt;/li&gt;
&lt;li&gt;Pipe findings into the team's existing ticketing flow. Security tools that don't connect to engineering workflows tend to be ignored.&lt;/li&gt;
&lt;li&gt;Use tags to exclude short-lived resources where scanning isn't useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per resource scanned per month.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon 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;Security Lake&lt;/a&gt; centralizes security data from AWS and third-party sources into a customer-owned S3 data lake, normalized to the OCSF schema. Athena, OpenSearch, and most SIEMs can query it directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A SOC pulls GuardDuty, CloudTrail, Route 53 logs, and EDR alerts into Security Lake, then runs cross-source Athena queries to correlate suspicious DNS lookups with API activity.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Define lifecycle policies up front. Security data accumulates fast.&lt;/li&gt;
&lt;li&gt;Subscribe consumers (Athena, OpenSearch, SIEM) per data type rather than giving everyone access to everything.&lt;/li&gt;
&lt;li&gt;Use OCSF normalization to your advantage when writing detections. Queries port between sources much more easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per GB ingested and per GB normalized. Underlying S3 storage is billed separately.&lt;/p&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; is a managed service that combines automation, tooling, and access to AWS Customer Incident Response Team (CIRT) experts to help triage and recover from security events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
GuardDuty raises a high-severity finding outside business hours. The service triages it automatically, escalates only what matters, and gives the on-call engineer a direct line to AWS CIRT if expert help is needed.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Don't wait for an incident to set it up. Define runbooks, contacts, and access boundaries while things are calm.&lt;/li&gt;
&lt;li&gt;Combine with Step Functions or Systems Manager Automation for repeatable response actions.&lt;/li&gt;
&lt;li&gt;Run tabletop exercises at least once a year.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Subscription-based. AWS service usage during a response is billed normally.&lt;/p&gt;




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

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

&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://aws.amazon.com/systems-manager/" rel="noopener noreferrer"&gt;AWS Systems Manager&lt;/a&gt; is broad, but a few of its tools are core to workload security: Session Manager replaces SSH bastions with auditable, port-less access to instances; Patch Manager automates OS and application patching; Parameter Store holds configuration values and secrets, with SecureString parameters encrypted by KMS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A company removes inbound port 22 from every EC2 security group. Engineers connect through Session Manager instead, with every session logged to S3 and CloudWatch. Patch Manager runs weekly inside a maintenance window, and compliance data flows into Security Hub so unpatched fleets are visible at the org level.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Use Session Manager instead of SSH bastions. Stream session logs to S3 with object lock and to CloudWatch for real-time review.&lt;/li&gt;
&lt;li&gt;Define custom patch baselines per OS, with auto-approval after a short test window for security and critical patches.&lt;/li&gt;
&lt;li&gt;Store secrets in Parameter Store SecureString (with a customer-managed KMS key) for low-volume config secrets. Use Secrets Manager for credentials that need rotation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Session Manager and Parameter Store standard parameters are free. Advanced parameters, Patch Manager on hybrid nodes, and other features have their own usage charges.&lt;/p&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; provides managed code signing for Lambda, container images, and IoT firmware. Signed artifacts can be verified at deploy time or runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A CI/CD pipeline signs every Lambda deployment package with Signer. Lambda is configured to reject unsigned or tampered packages, so a malicious push to a build artifact bucket can't quietly become production code.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Make signing part of the pipeline, not a manual step.&lt;/li&gt;
&lt;li&gt;Protect signing profiles with KMS and tight IAM.&lt;/li&gt;
&lt;li&gt;Only sign artifacts that have actually passed tests and security checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per signing job.&lt;/p&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;, which went GA in April 2026, is an AI-driven security agent that performs continuous, context-aware penetration testing across cloud, multicloud, and on-prem environments. It's designed to behave like a human pentester rather than a static scanner.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
The agent runs continuously against a staging environment, finding a chain that combines an exposed metadata endpoint with a permissive IAM role into a privilege escalation path. It writes up the finding with reproduction steps, and the team fixes the chain before it reaches production.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Start in non-production to calibrate noise and false positives.&lt;/li&gt;
&lt;li&gt;Connect findings to your existing vulnerability management workflow.&lt;/li&gt;
&lt;li&gt;Treat it as a complement to Inspector and traditional SAST/DAST, not a replacement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Based on scope and scan frequency.&lt;/p&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;Verified Permissions&lt;/a&gt; is a managed authorization service based on the Cedar policy language. It centralizes fine-grained permission decisions for application users, separate from IAM (which governs AWS resources).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A banking app needs to decide whether a given user can view, edit, or close a specific account. Instead of scattering &lt;code&gt;if user.role == "admin"&lt;/code&gt; checks throughout the codebase, the app calls Verified Permissions with the request context and gets a clean allow/deny back.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Keep policies in version control alongside code. Cedar is text and reviews well in pull requests.&lt;/li&gt;
&lt;li&gt;Model policies on real business rules, not just technical roles.&lt;/li&gt;
&lt;li&gt;Use Cognito or your IdP for authentication and Verified Permissions for the decisions that follow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per authorization request.&lt;/p&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;Config&lt;/a&gt; records the configuration state of AWS resources over time and continuously evaluates them against rules. It's the backbone of most CSPM and compliance automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A Config rule detects an S3 bucket that just had &lt;code&gt;BlockPublicAccess&lt;/code&gt; disabled. An automatic remediation Lambda re-enables the setting and notifies the owning team via SNS.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enable it in every account through Organizations and aggregate findings centrally.&lt;/li&gt;
&lt;li&gt;Use Conformance Packs for frameworks like CIS, NIST, or PCI rather than building rules from scratch.&lt;/li&gt;
&lt;li&gt;Be selective about which resource types you record. Recording everything in a busy account adds up quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per configuration item recorded and per rule evaluation.&lt;/p&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 evidence collection for compliance frameworks like SOC 2, ISO 27001, HIPAA, and PCI DSS. It maps AWS resource data to controls so audit prep is mostly continuous instead of a quarterly fire drill.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A compliance officer creates an ISO 27001 assessment. Audit Manager pulls encryption settings, IAM data, and CloudTrail logs into structured evidence that's ready for the auditor, with no manual screenshots required.&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 frameworks and customize them. Don't start from a blank page.&lt;/li&gt;
&lt;li&gt;Assign control owners explicitly, otherwise everything ends up as "the security team's problem."&lt;/li&gt;
&lt;li&gt;Review collected evidence in advance of audits, not the night before.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Per active assessment per month.&lt;/p&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;Artifact&lt;/a&gt; is the self-service portal for AWS's own compliance reports (SOC 1/2/3, ISO certifications, PCI attestations, and similar) plus customer-facing agreements like the BAA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;br&gt;
A new enterprise customer asks for AWS's PCI DSS Attestation of Compliance during procurement. The security team pulls the latest report from Artifact instead of opening a support case.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Refresh reports each audit cycle so you're not handing out stale documents.&lt;/li&gt;
&lt;li&gt;Restrict Artifact access to people who actually need it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing&lt;/strong&gt;&lt;br&gt;
Free.&lt;/p&gt;




&lt;p&gt;This post covers all AWS security-related services as of April 2026.&lt;/p&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://forem.com/aws-builders/how-to-create-external-root-ca-and-intermediate-ca-in-aws-acm-pca-to-issue-private-certificates-56gm</link>
      <guid>https://forem.com/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://forem.com/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-with-terraform-3lc1</link>
      <guid>https://forem.com/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://forem.com/aws-builders/how-to-restrict-default-access-to-kms-via-key-policy-28gc</link>
      <guid>https://forem.com/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://forem.com/aws-builders/how-to-track-cognito-identity-pool-iam-access-roles-api-calls-via-athena-32eo</link>
      <guid>https://forem.com/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://forem.com/aws-builders/how-to-track-cloudtrail-api-calls-from-all-organizations-aws-accounts-using-athena-1dk4</link>
      <guid>https://forem.com/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://forem.com/aws-builders/automated-way-to-restrict-all-inbound-and-outbound-rules-from-aws-default-security-groups-22o1</link>
      <guid>https://forem.com/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>
