AWS Marketplace

Securing access to AMIs in AWS Marketplace

Most of the customers I talk to manage large catalogs of paid software products procured from AWS Marketplace, including a mix of AWS Marketplace SaaS Contracts, hourly/monthly/annual Amazon Machine Images (AMIs), and products procured via Seller Private Offers. Customers often also ask me to explain best practices around securing access to paid software products in AWS Marketplace. In this post, I will share tips and tricks on how you can secure paid AMIs and subscriptions in AWS Marketplace by using the principle of least privilege, which grants only the permissions required to perform a task.

AWS Security Best Practices apply to AWS Marketplace, too. The principle of least privilege plays an important role in securing your AWS account, your AWS Marketplace AMIs, and your AWS Marketplace subscriptions. Here are three simple rules you can follow to tighten security around your paid software products:

  1. Rule 1: Only those users who are authorized to accept an End-User License Agreement (EULA) on behalf of your organization should be allowed to procure (or subscribe to) a product in AWS Marketplace.
  2. Rule 2: Once you have procured the software product from AWS Marketplace, unauthorized users should not be able to launch the paid software from AWS Marketplace.
  3. Rule 3: You should distribute your paid product only to authorized users of that product. You also want to ensure that governance is built into the process.

Rule 3 also extends to other IT services. A service like AWS Service Catalog can be used to enable users while achieving consistent governance.

securing aws marketplace amis

Notes:

  • This post does not cover how to secure Amazon EC2 instances running paid software. The AWS Identity and Access Management (IAM) permissions and strategy for securing EC2 instances not running paid software can be re-used with modifications to accommodate security of EC2 instances running paid software as well. However, it does include IAM permissions for preventing replication of paid AMIs.
  • If you have multiple AWS accounts, you need to secure each of your AWS accounts.

Rule 1: Only those users who are authorized to accept a EULA on behalf of your organization should be allowed to procure (or subscribe to) a product in Marketplace.

You will first need to grant permissions to a select group of people from your organization to give them subscription access to AWS Marketplace. Individuals in this group will need to be able to accept a EULA of the subscription/software product on behalf of your organization. Since this has legal implications, I advise you to create a central team in your organization that controls software procurement. The software procurement team should get a legal opinion before making the purchase.

Then, to avoid unexpected subscriptions or cancellations, you need to explicitly deny AWS Marketplace subscription access from your users. All remaining users in the organization should not have access to subscribe or unsubscribe to a software product in AWS Marketplace.

Tip:

If you are procuring a software product in AWS Marketplace, check to see if your purchase is eligible for Seller Private Offers for a volume discount on the software.

Grant AWS Marketplace permissions to your procurement team

If you do not have a central procurement team, I advise you to create one. Once you have created an IAM user group for your procurement team, you need to associate the policy below with your procurement team’s IAM user group/federated role to enable them to procure a software product in AWS Marketplace.

Recommendations:

  • Create an IAM group and associate the policy with that group. IAM groups offer management convenience.
  • Create customer-managed policies and associate those policies with your IAM users/groups/roles. This offers management convenience. For more information, see documentation on Choosing Between Managed Policies and Inline Policies.
{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Action": [

                "aws-marketplace:ViewSubscriptions",

                "aws-marketplace:Subscribe",

                "aws-marketplace:Unsubscribe",

                "ec2:DescribeInstances",

                "ec2:DescribeAccountAttributes"

            ],

            "Effect": "Allow",

            "Resource": "*"

        }

    ]

}

Notes:

  • To unsubscribe to a product, you must not have any running instances of that paid product during the unsubscription process.
  • To find out more about how to create an IAM policy and attach it to a principal, see the documentation for:

Instead of one single group, some of my customers’ procurement teams consist of two separate groups: one that decides to purchase a software product and another that manages the billing. The group that makes the decision and accepts the terms and conditions of a purchase needs to have the policy permissions described in the preceding section. The billing management group may still need permissions to view purchases. To give your billing management group permissions, associate the following policy with them.

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Action": [

                "aws-marketplace:ViewSubscriptions"

            ],

            "Effect": "Allow",

            "Resource": "*"

        },

       {

            "Action": [

                "aws-marketplace:Subscribe",

                "aws-marketplace:Unsubscribe",

            ],

            "Effect": "Deny",

            "Resource": "*"

        }

    ]

}

You might also want to give your billing group the ability to view bills and use the cost explorer. The AWS documentation has several recommended IAM policies you can use based on your requirements. For more information, see the documentation on Billing and Cost Management Policy Examples.

Revoke AWS Marketplace permissions from your IAM users

Now that you have given appropriate permissions to your procurement team, you need to revoke permissions from the rest of your organization’s IAM users and explicitly deny access to subscribing or unsubscribing to a paid product. To do so, you need to associate the following policy with appropriate IAM user groups/federated roles.

{

            "Version": "2012-10-17",

            "Statement": [{

                                    "Sid": "DenyAWSMarketplaceAccess",

                                    "Effect": "Deny",

                                    "Action": ["aws-marketplace:*" ],

                                    "Resource": "*"

                        }]

}

Notes:

  • You must not associate this policy with the procurement/billing (if applicable) team’s IAM user groups/federated roles. Since the Deny effect takes precedence over the Allow effect, if you associate the above policy with the procurement team, they will not be able to perform view/subscribe/unsubscribe operations using the AWS Marketplace console.
  • If you have multiple AWS accounts, you need to do this in each child account.
  • If your users are signing in using IAM user accounts instead of federated roles, you can create an IAM Group, such as No-Marketplace-Access, and add users outside of your procurement and billing team IAM users to the group. You can then associate the SID:DenyAWSMarketplaceAccess policy as a customer-managed policy to the new IAM group. This way, you will be able to manage policies and access centrally.

The above policy revokes an IAM user’s ability to view paid purchases, subscribe to a new product, and cancel an existing product subscription. However, the above policy does not prevent a user from launching paid resources. If you have a subscription to an AMI-based product, your IAM user will still be able to launch the paid AMI even with the permissions mentioned in the previous section.

Before you proceed to the next section and tighten security around your paid products, review your existing AWS Marketplace subscriptions. Ensure that your account has no unauthorized product subscriptions. For documentation, see How do I see my software subscriptions in AWS Marketplace.

Rule 2: Once you have procured the software product from AWS Marketplace, unauthorized users should not be able to launch the paid software.

To prevent your users from launching paid AMIs and AMIs from independent software vendors (ISVs), you can utilize the following policy and associate it with their IAM user/group/role. Update your account id in the following list and add any account IDs belonging to AMIs you do not want to blacklist.

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "DenyMarketplaceAMIAccess",

            "Effect": "Deny",

            "Action": [

                "ec2:RunScheduledInstances",

                "ec2:RunInstances"

            ],

            "Resource": "arn:aws:ec2:*::image/ami-*",

            "Condition": {

                "StringNotEquals": {

                    "ec2:Owner": [

                        "amazon",

                        "self",

                        "Update_your_account_id_here"

                    ]

                }

            }

        }

    ]

}

Notes:

  • Some AMIs distributed by Amazon do not have Amazon identified as the owner. Instead, they are distributed with a custom account number. For example, the AWS Deep Learning AMI has a custom account number in the owner field. If you do not want to blacklist these Amazon AMIs, you need to include the appropriate custom account number in the above policy.
  • If you are also selling an AMI in AWS Marketplace using your AWS account, you need to write additional IAM policies to manage the permissions for that AMI.
  • If you have a multi-account setup and you are deploying standardized AMIs distributed by other accounts, you need to include the AMI owner’s account number in the above policy. (For more information, please refer to this whitepaper)

The DenyMarketplaceAMIAccess policy above only allows your users to launch your private AMIs or public AMIs provided by AWS. You can tighten the above policy further by allowing your users to launch only your private AMIs by removing “amazon” from the ec2:Owner contents of the condition block in the policy from preceding section with the following contents.

"StringNotEquals": {

                    "ec2:Owner": [

                        "self",

                        "Update_your_account_id_here"

                    ]

                }

The DenyMarketplaceAMIAccess policy also removes a user’s ability to launch another public AMI instance from an instance running the paid product from AWS Marketplace. Users can no longer select an instance running the paid software from AWS Marketplace and use the Action drop-down menu item called Launch More Like this in the Amazon EC2 console. However, they can choose an instance running a paid software product, create a private AMI, and launch an EC2 instance as a private AMI. Since the product code of the paid AMI is replicated into the private AMI and any snapshots of the volume, your AWS account will be charged if they launch such a private paid AMI. This brings up the following launch and replication related aspects of security:

  1. Secure against unauthorized replication of paid software.
  2. Secure against the unauthorized launch of a private paid AMI.

Secure from unauthorized replication of paid AMIs

You need to ensure that your users do not have the capability to replicate paid AMIs. Typically, a pre-defined process creates, maintains, and deletes an AMI so that only that process will have access to these capabilities. To take it a notch further, you can define IAM policies for the process in such a way that the process only has access to the AMI that it intends to maintain. You can achieve some of this via tags and tags-based IAM policies. To ensure that your IAM users are not able to create a private paid AMI from a volume/AMI/snapshot, associate the following policy with your users:

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "DenyAMIMaintenanceAccess",

            "Effect": "Deny",

            "Action": [

                "ec2:CreateSnapshot",

                "ec2:CreateImage",

                "ec2:CopyImage",

                "ec2:CopySnapshot",

                "ec2:DescribeSnapshots",

                "ec2:DeregisterImage",

                "ec2:DeleteSnapshot",

                "ec2:ModifyInstanceAttribute"

            ],

            "Resource": "*"

        }

    ]

}

You need to also ensure that your IAM users do not have any other way to replicate the volume or create the snapshots of the paid AMI’s root volume (access keys, managed services, or third party software, etc.). Apart from not allowing them to create a private paid AMI, you also need to restrict users from launching a private paid AMI.

Before we discuss tips and tricks for securing against the launch of private paid AMIs, here are some of the best practices to apply to private paid AMIs:

  • Refresh your private AMI often with the latest security patches.
  • Paid product sellers often release newer versions of the paid products. Ensure that you track what you have baked into the AMI so that you are not bound to a specific version of the paid AMI.
  • Regularly check the health of your AMI. Here is a post on how you can set up a process to regularly identify security vulnerabilities in your AMI.
  • Ensure that your AMI creation process is not creating any unmanaged volumes or snapshots that contain AWS Marketplace product software. If you are creating snapshots or volumes for backups, ensure that you have proper IAM policies in place for securing those.
  • Ensure the security of key pairs, if used for EC2 instances. Unauthorized users should not have access to the key pair.

Secure against the unauthorized launch of a private paid AMI

If you have created private AMIs from AWS Marketplace-based paid AMIs, you need to attach AMI-specific Deny policies to your IAM users. An elegant way to apply this restriction is by using tags.

For this example, we will use a tag AMI-TYPE=paid for managing your private paid AMIs. You first need to tag all of your private AMIs with the tag key set to AMI-TYPE and tag value set to paid. Also be sure that your process to create private paid AMIs always includes that corresponding tag.

Next, you need to create the following policy and associate it with your users. This prevents them from being able to launch any AMI with the tag AMI-TYPE=paid.

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "DenyPrivatePaidAMIAccess",

            "Effect": "Deny",

            "Action": [

                "ec2:RunScheduledInstances",

                "ec2:RunInstances"

            ],

            "Resource": ["arn:aws:ec2:*::image/ami-*"],

            "Condition": {

                "ForAnyValue:StringEqualsIgnoreCase": {

                    "ec2:ResourceTag/AMI-TYPE": "Paid"

                }

            }

        }

    ]

}

Note:

This policy does not restrict users from stopping, starting, or rebooting an existing paid instance. It also does not restrict users from attaching or detaching paid root volumes that have product codes attached. If you have such a requirement, you would need to write corresponding IAM policies.

Although users cannot launch an instance of the private paid AMI that you have tagged with AMI-TYPE=paid, they can modify the tag itself and launch an instance of the private paid AMI after modifying the tag. You need to ensure that users cannot edit the tag. To do so, attach following policy with your IAM users.

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Sid": "DenyTagsForExistingAMIs",

            "Effect": "Deny",

            "Action": [

                "ec2:DeleteTags",

                "ec2:CreateTags"

            ],

            "Resource": "arn:aws:ec2:*::image/ami-*",

            "Condition": {

                "StringEqualsIgnoreCase": {

                    "ec2:ResourceTag/AMI-TYPE": "paid"

                }

            }

        },

        {

            "Sid": "DenyCreationOfPaidTags",

            "Effect": "Deny",

            "Action": [

                "ec2:DeleteTags",

                "ec2:CreateTags"

            ],

            "Resource": "arn:aws:ec2:*::image/ami-*",

            "Condition": {

                "StringEqualsIgnoreCase": {

                    "aws:RequestTag/AMI-TYPE": "paid"

                }

            }

        }

    ]

}

This IAM policy prevents them from modifying tags of AMIs that already contain the AMI-TYPE=paid tag and prevents them from creating such a tag. You can optionally identify AMI-TYPE as a cost-allocation tag. Here are additional things you can do to further tighten security:

  1. Tighten tag creation capabilities by specifying a Deny policy for all tag key-value pairs except tags you want to allow a specific principal can apply.
  2. You can allow users to tag only specific resources. For example, you can allow your users to create tags only on instances which already have environment=production tag. To know more how to achieve this, see Tagging Resources.

As a best practice:

  • You may also want to restrict users from launching resources in specific AWS regions. To learn more and see a sample IAM policy, see Restricting Access to a Specific Region and Easier way to control access to AWS regions using IAM policies.
  • Instead of allowing your users to launch all AMIs, you can also whitelist which AMIs they can launch with a tagging strategy. This also aligns with principle of least privilege.
  • If you are an organization with a multi-account setup that uses consolidated billing and you standardize primary and Disaster Recovery (DR) regions/Availability Zones (AZs) and specific instance-types/families across your multiple AWS accounts, you will be able to better predict the number of Reserved Instances you need for optimizing your EC2 usage cost.

Before you move to distributing the paid AMIs, ensure that you have reviewed your IAM users’ permissions and a list of currently running paid product instances.

Rule 3: You should distribute your paid product only to authorized users for that product. Additionally, you want to ensure that governance is built into the process.

AWS Service Catalog provides a way to distribute the products in an organized fashion while ensuring that governance is built in. If you have more than a couple of products and more than a couple of users, AWS Service Catalog is the recommended way for distributing the software products from AWS Marketplace. AWS Service Catalog automatically associates the principal-ARN with the resources provisioned as part of the stack. This gives you insight into the ARN of the principal that launched a specified product. To know more about how you can distribute products procured from AWS Marketplace, see my previous post on Use AWS Service Catalog to build a custom catalog of products from AWS Marketplace.

Note:

  • It is a best practice to standardize paid and subscription AMIs in AWS Marketplace before you distribute the AMI to your business units. The standardization process involves hardening, inspection, and validation of an AMI before distribution. The standardization process can also include custom scripts that you can execute to ensure that the AMI meets your security and compliance needs. To find out more about a sample pipeline you can customize and use for standardization of an AMI, see Announcing the Golden AMI Pipeline.

A way to scale the management of paid AMIs is via AWS Service Catalog. If you do not choose to use AWS Service Catalog, you can tag public AMIs and write tag-based IAM policies to grant authorized IAM principal(s) permissions to deploy EC2 instance of a paid AMI. Remember that a Deny policy overrides an Allow policy hence ensure that you have appropriate IAM policies associated with the user who needs to have access to the paid AMI.

The tags you assign to the public AMI are available only to your AWS account.

Most importantly, thoroughly test IAM policies you create and apply before you roll them out.

Conclusion

To tighten security around your paid AMI products from AWS Marketplace, I always recommend following the principle of least privilege and only granting users access to the resources they need. In this post, I showed a way to implement that principle for securing paid AMIs you have subscribed to, along with some recommendations and best practices. You can secure your AWS infrastructure further by following the principle of least privilege and only granting principals the access to resources they need to access.

About the Author

Kanchan WaikarKanchan Waikar is an AWS Marketplace Solutions Architect at Amazon Web Services. She enjoys helping customers build architectures using AWS, AWS Marketplace products, and AWS Service Catalog.