lyft / metadataproxy

A proxy for AWS's metadata service that gives out scoped IAM credentials from STS
Other
456 stars 69 forks source link

Principals used for Docker Container Role Trust Not Appropriate #59

Closed concat closed 7 years ago

concat commented 7 years ago

The example you show for the trust relationship to not the best:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::012345678901:root",
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

== The "AWS": "arn:aws:iam::012345678901:root" principal will give ANY iam user or role from account 012345678901 the right to assume this ContainerRole, not a specific user as you indicate in your documentation. In particular, "root" has nothing to do with the "root" user on the Docker EC2 Host OS system. It is just one form that can be used with IAM to indicate the entire account.

The other Principal in the example: "Service": "ec2.amazonaws.com" grants the EC2 service rights to assume a role, but this role was already used in your "chain" to get the security credentials of the ContainerRole. It is the ContainerRole which needs to be in your trust:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::12345678901:role/DockerHostRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The trust is presenting this, not the EC2 service, when it is making the request.

The "aws sts assume-role --role-arn" cli is useful to debug these issues. It is what I used when working through the IAM role configuration.

Stephen

ryan-lane commented 7 years ago

Well, so I think it heavily depends on what you're trying to do here. The example is meant to be as generic as possible.

For "AWS": "arn:aws:iam::012345678901:root", we're saying "any IAM user/role in this account is allowed to assume this role, if the IAM policy in that user/role allows it to assume the role. Sure, it's possible to scope this further, to specific roles or users, but the assumption is that you're controlling access to the IAM policy of your users and roles, which in general makes the scoping laborious. Also, we write it this generically it makes it way easier to deal with user support for the service. In my opinion, if you're already managing IAM well, this isn't any less secure (not saying you can't choose to make it more secure, though).

For "Service": "ec2.amazonaws.com", I didn't want to assume folks weren't also using these IAM roles attached to instances (through instance profiles). It's here to make the policy generic and to ease support.

If you want to make the docs clearer on how the policies work and ways in which to scope access more granular, I'm happy to get a PR for this. :)

ryan-lane commented 7 years ago

I do want to make sure I clarify this issue a bit, for folks that may search and find this:

AWS": "arn:aws:iam::012345678901:root", <-- this does not allow any IAM user or role access to assume this role. This makes it possible to grant access to any IAM user or role in the account to assume the role. To actually allow a user or role to assume the role, it's still necessary to grant the AssumeRole action for the role's ARN in the IAM user/role's IAM policy.

concat commented 7 years ago

Thanks. You are right about the need for the trusted account to grant the IAM role - I misunderstood the AWS documentation - it said potentially anyone/anyrole in the trusted account but then went on to explain the need to grant the role on the trusted side.

And thanks for clarifying why you left the ec2.amazonaws.com as a Principal in the trust policy.