avatarTeri Radichel

Summarize

Sharing an Encrypted AMI Programmatically

ACM.216 A script to share an encrypted AMI with our existing KMS Key CloudFormation template

Part of my series on Automating Cybersecurity Metrics. The Code.

Free Content on Jobs in Cybersecurity | Sign up for the Email List

I showed you how to manually share an AMI with another account and some of the issues with encrypted AMIs.

Here’s how you can share an encrypted AMI programmatically.

First you need to ensure that the users in the other account can access the key. That is a matter of adding the users that need to use the AMI to the KMS key profile.

Next, we can use the modify-image-attribute command to grant the other account access to the AMI.

In the following code, I retrieved an AWS account number into the $account parameter and the AMI id into the $linuxami parameter. Then I can call the command like this:

When I create an AMI, I typically retrieve the AMI ID and store it in a parameter for later reference. More on that possibly later.

Now if you share this AMI and try to run it in the external account what do you think is going to happen? Refer to my prior posts. You’ll start the instance in the account to which it has been shared and it will immediately terminate. You may or may not be able to find any indiciation in any logs within AWS as to what is the problem.

AWS, is this by design? Because this has been happening forever, I’ve written about it a bunch of times, and it is still not fixed. It’s a very confusing and hard to troubleshoot error for someone who is new to security and trying to do the right thing — encrypt their data with a KMS key with restricted permissions. Why make it so difficult?

I hope some day AWS makes this easier. It has been a problem that created a lot of angst and wasted time since I worked on the original Capital One cloud team (pre-breach) and it is still an issue.

Anyway, we need to add permission for the external account to use the KMS key. We have a generic key template I’ve been modifying over the course of this series to support differnet scenrios.

Let’s add the ability to pass in a list of accounts that are allowed to use the KMS key. The key policy is too long to share here and I will reiterate now that I don’t think you should take this approach unless you have people managing this policy that really know what they are doing and you can thoroughly test it in a proper manner. The issues that exist with service control policies across your organization apply to any shared code.

I showed you how to create a policy that allows another account to use the key in this post:

We also did some troubleshooting here:

Let’s add the permissions to our key policy for the new account(s):

        {
            "Sid": "Allow new sandbox account to use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::xxxxxxxxxxxx:root"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey",
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*"
        },

Recall that when you use the root option as shown above to administer the key, that permission last time I wrote about it applied to adminstrators in the remote account. It would be better to create a zero-trust key policy for the users in the remote account but I’m going to keep it simple for this post and add the account as shown above.

In my key policy, I already have statements for encryption and decryption.

What I want to do is add the accounts that I want to share the key with to the list of principals that can use the key to encrypt or decrypt, so I really don’t need to change my key policy at all. What I need to change is the list of ARNs I pass into the key template when creating it to include the remote accounts.

For the code I’m working with I have a mechansim to retrieve the account number. I can simply append it to my existing list of encrypt and decrypt arns that we’ve been using throughout this series to create key policies.

Recall that I call the function that runs the KMS key cloud formation template as follows — and nothing needs to change:

Redeploy the key and verify that the remote account now exists in the policy for encrypt and decrypt.

As a final test, try to deploy an EC2 instance with the shared AMI and verify that you no longer get the mysterious failure.

Follow for updates.

Teri Radichel | © 2nd Sight Lab 2023

The best way to support this blog is to sign up for the email list and clap for stories you like. That also helps me determine what stories people like and what to write about more often. Other ways to follow and support are listed below. Thank you!

About Teri Radichel:
~~~~~~~~~~~~~~~~~~~~
Author: Cybersecurity for Executives in the Age of Cloud
Presentations: Presentations by Teri Radichel
Recognition: SANS Difference Makers Award, AWS Security Hero, IANS Faculty
Certifications: SANS
Education: BA Business, Master of Software Engineering, Master of Infosec
Company: Cloud Penetration Tests, Assessments, Training ~ 2nd Sight Lab
Like this story? Use the options below to help me write more!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
❤️ Clap
❤️ Referrals
❤️ Medium: Teri Radichel
❤️ Email List: Teri Radichel
❤️ Twitter: @teriradichel
❤️ Mastodon: @[email protected]
❤️ Facebook: 2nd Sight Lab
❤️ YouTube: @2ndsightlab
❤️ Buy a Book: Teri Radichel on Amazon
❤️ Request a penetration test, assessment, or training
 via LinkedIn: Teri Radichel 
❤️ Schedule a consulting call with me through IANS Research

My Cybersecurity Book: Cybersecurity for Executives in the Age of Cloud

Permission
Ami
Automate
Kms
Cross Account
Recommended from ReadMedium