Packer: A more complete AWS IAM policy sample for the docs

Created on 19 Feb 2015  ·  15Comments  ·  Source: hashicorp/packer

One for the documentation staffers. This was a little lengthy to obtain, but it's a more complete IAM policy that should suit the documentation - just swap out the ALL_CAPS for the right terms. I thought it would be good to put in the docs, given there's some non-intuitive IAM stuff in there.

The policy is intended to limit the packer user to a single subnet in a VPC, and limit the destruction to things packer creates itself.

Notes

  • Swap out the account ID, vpc ID and subnet ID
  • DeleteKeypair and DeleteSnapshot cannot be resource restricted, according to AWS support
  • Built up from the current minimal IAM set in the docs (I'm a packer newbie, still finding my way around)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "NonResourceLevelPermissions",
            "Action": [
                "ec2:Describe*",
                "ec2:CreateVolume",
                "ec2:CreateKeypair",
                "ec2:DeleteKeypair",
                "ec2:CreateSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:CreateImage",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot",
                "ec2:RegisterImage",
                "ec2:CreateTags",
                "ec2:ModifyImageAttribute"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Sid": "AllowInstanceActions",
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "ec2:AttachVolume",
                "ec2:DetachVolume",
                "ec2:DeleteVolume"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:instance/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:volume/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:security-group/*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:ResourceTag/Name": "Packer Builder"
                }
            }
        },
        {
            "Sid": "EC2RunInstancesSubnet",
            "Effect": "Allow",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": [
                "arn:aws:ec2:us-east-1::image/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:key-pair/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:network-interface/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:security-group/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:volume/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:instance/*",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:subnet/SUBNET_ID",
                "arn:aws:ec2:us-east-1:ACCOUNT_ID:vpc/vpc-*"
            ]
        },
        {
            "Sid": "SGVPCDelete",
            "Effect": "Allow",
            "Action": [
                "ec2:DeleteSecurityGroup"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "StringEquals": {
                    "ec2:vpc": [
                        "arn:aws:ec2:us-east-1:ACCOUNT_ID:vpc/VPC_ID"
                    ]
                }
            }
        }
    ]
}
need-documentation

Most helpful comment

I really wish you guys would reopen this. Having a secure environment is not a "power user" feature.

All 15 comments

:+1: and for those that use a different region, also just replace us-east-1 with your region ... Thanks @vacri :smile:

Just noticed this while searching around for docs on how to do something with Packer and IAM and noticed the policy above has a security loophole you might care about (and since I referenced these docs yesterday, people like me would too :smile:).

It allows the ec2:CreateTags action for _everything_ and then restricts dangerous things like ec2:StopInstances and ec2:terminateInstances to instances with a specific tag. Something with malicious intent can just add the right tag and have access to those potentially-dangerous actions. Its frustrating that there's no good way to restrict ec2:CreateTags to specific resources to prevent it. Hope this helps!

Hrm... you may be able to add a Condition to limit stop/terminate to a specific subnet/VPC - similar to the Condition for the DeleteSecurityGroup section - so that it will only work on instances in that subnet? Unfortunately I'm flat-chat at the moment and can't try it out.

I agree that it's not watertight, but it is a lot more restrictive than the MVP policy in the docs. I was initially after something that just prevented me from fat-fingering a config and scribbling over the wrong EC2 resources... and it grew from there. :)

I didn't notice the 'tag hole', though - nice find

You can, I'm doing that in other places. I also use a policy to force it to
launch instances with a specific instance profile/IAM role, then restrict
stopping and terminating to only instances with that profile. So, for
example, if you have an IAM role for Jenkins slaves you force the Jenkins
master to launch them with the slave role, and Jenkins is only allowed to
terminate instances with that slave role. It's awkward but permanent for
the lifetime of the VM so it can't be subverted.

I can't take all the credit for that 'tag hole', I saw it somewhere I can't
remember on the Internet and it stuck with me because it would be such a
great way to do what we're talking about, if not for the loophole. Oh well.
Figuring out how to bend IAM policies to your will gets tedious quickly lol.

On Tue, Aug 4, 2015, 8:08 PM vacri [email protected] wrote:

Hrm... you may be able to add a Condition to limit stop/terminate to a
specific subnet/VPC - similar to the Condition for the DeleteSecurityGroup
section - so that it will only work on instances in that subnet?
Unfortunately I'm flat-chat at the moment and can't try it out.

I agree that it's not watertight, but it is a lot more restrictive than
the MVP policy in the docs. I was initially after something that just
prevented me from fat-fingering a config and scribbling over the wrong EC2
resources... and it grew from there. :)

I didn't notice the 'tag hole', though - nice find


Reply to this email directly or view it on GitHub
https://github.com/mitchellh/packer/issues/1928#issuecomment-127809900.

@gdhaworth mind sharing your policy?

Dont' mean to necro-thread but since this is still open...
I haven't fully verified the following but I believe this closes the Tagging hole and more closely focuses perms. I'll post the full schema once I've tested it.

    {
        "Sid": "RoleLocked",
        "Action": [
            "ec2:StartInstances",
            "ec2:StopInstances",
            "ec2:RebootInstances",
            "ec2:TerminateInstances",
            "ec2:ModifyInstanceAttribute",
            "ec2:GetPasswordData",
            "ec2:AttachVolume",
            "ec2:DetachVolume",
            "ec2:CreateSnapshot",
            "ec2:DeleteSnaphot",
            "ec2:AuthorizeSecurityGroup*",
            "ec2:RevokeSecurityGroup*",
            "ec2:CreateTags"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "ArnEquals": {
                "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT:instance-profile/packer"
            }
        }
    },
    {
        "Sid": "VpcLocked",
        "Action": [
            "ec2:DescribeSecurityGroups",
            "ec2:DescribeSubnets"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "ArnEquals": {
                "ec2:vpc": "arn:aws:iam::ACCOUNT:vpc/vpc-ID"
            }
        }
    },
    {
        "Sid": "RegionLocked",
        "Action": [
            "ec2:Describe*",
            "ec2:CreateVolume",
            "ec2:DeleteVolume",
            "ec2:CreateImage",
            "ec2:CreateKeyPair",
            "ec2:DeleteKeyPair",
            "iam:GetInstanceProfiles",
            "iam:ListInstanceProfiles"
        ],
        "Effect": "Allow",
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                "ec2:Region": "us-east-1"
            }
        }
    },
    {
        "Sid": "General",
        "Action": [
            "sts:DecodeAuthorizationMessage"
        ],
        "Effect": "Allow",
        "Resource": "*"
    },

This is what I came up with, its based of https://blogs.aws.amazon.com/security/post/Tx1ZU3LW4LLPQY2/How-to-Help-Lock-Down-a-User-s-Amazon-EC2-Capabilities-to-a-Single-VPC

{
  "Statement": [
    {
      "Action": [
        "ec2:Describe*",
        "ec2:CreateKeyPair",
        "ec2:DeleteKeyPair",
        "ec2:CreateImage",
        "ec2:DescribeKeyPairs",
        "ec2:CreateSecurityGroup",
        "iam:GetInstanceProfiles",
        "iam:ListInstanceProfiles",
        "ec2:CreateTags"
      ],
      "Effect": "Allow",
      "Resource": "*"
    },
    {
      "Action": [
        "iam:PassRole"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:iam::ACCOUNT_ID:role/eu-west-1-inflight_packer_run"
    },
    {
      "Action": [
        "ec2:StartInstances",
        "ec2:StopInstances",
        "ec2:RebootInstances",
        "ec2:TerminateInstances",
        "ec2:ModifyInstanceAttribute",
        "ec2:GetPasswordData",
        "ec2:AttachVolume",
        "ec2:DetachVolume",
        "ec2:CreateSnapshot",
        "ec2:DeleteSnaphot",
        "ec2:AuthorizeSecurityGroup*",
        "ec2:RevokeSecurityGroup*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT_ID:instance-profile/eu-west-1-inflight_packer_run"
        }
      },
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Condition": {
        "StringEquals": {
          "ec2:InstanceProfile": "arn:aws:iam::ACCOUNT_ID:instance-profile/eu-west-1-inflight_packer_run"
        }
      },
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:instance/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Effect": "Allow",
      "Resource": "arn:aws:ec2:eu-west-1:ACCOUNT_ID:subnet/*"
    },
    {
      "Action": "ec2:RunInstances",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:volume/*",
        "arn:aws:ec2:eu-west-1::image/*",
        "arn:aws:ec2:eu-west-1::snapshot/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:network-interface/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:key-pair/*",
        "arn:aws:ec2:eu-west-1:ACCOUNT_ID:security-group/*"
      ]
    }
  ],
  "Version": "2012-10-17"
}

@imduffy15 thanks for the example and pointer to the blog post! This was a big help.

I think a few of your conditions aren't valid (see http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ec2-api-permissions.html#ec2-api-unsupported-resource-permissions) --

both ec2:DeleteSnapshot, ec2:ModifyInstanceAttribute don't support conditions according to the docs.

Also, it seems like you are missing some of the permissions in the packer docs (https://www.packer.io/docs/builders/amazon.html) ? Like ec2:CreateVolume, ec2:RegisterImage, ec2:ModifyImageAttribute.

FWIW, here is my attempt -- https://gist.github.com/ogrodnek/00419e085d2d915b262e7f1fe42626d0

Agree it would be worth flushing out the official docs a bit more. Also hoping the EC2/IAM support in AWS improves...

@ogrodnek any idea if its possible to restrict CreateKeyPair DeleteKeyPair CreateTags etc.

@imduffy15 unfortunately it looks like it's not currently supported for those keys, see: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ec2-api-permissions.html#ec2-api-unsupported-resource-permissions

specifically: _The following Amazon EC2 API actions currently do not support resource-level permissions; therefore, to use these actions in an IAM policy, you must grant users permission to use all resources for the action by using a * wildcard for the Resource element in your statement. You cannot use Amazon EC2 condition keys for these actions_

It's really unfortunate. I'm hopeful this is something that will continue to improve. I think we'll have to watch the docs/announcements for if/when restrictions are supported there.

I'm glad there's a discussion here, but I think this is more of a power-user feature, and might be best to be documented in github. For now, I think we want to keep the docs as simple as possible.

I really wish you guys would reopen this. Having a secure environment is not a "power user" feature.

@tedivm The problem is that "secure" depends on the context and when IAM get more capabilities this changes. Also one can argue that the most secure way of building AMI's are by using a separate build account and not trying to restrict IAM in an account used for multiple purposes.

I actually do recommend that, where feasible, people build in separate accounts. However, there are still cases where that isn't really feasible. I don't see any harm in giving people more complete instructions for locking down packer- it can be in an "advanced" section if you're worried about scaring off new users.

I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings