-
Notifications
You must be signed in to change notification settings - Fork 9.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: Exclusive policy attachment list for users, groups, and roles #4426
Comments
Following. I thought terraform already did this. Yikes. Major security hole here. |
@lorengordon it's by design. |
It can certainly be one thing to you and another to me and our auditors. Call it whatever you like. We call it a security risk. We want to use terraform to manage infrastructure as code. We create the IAM role with terraform and we create the IAM policies with terraform. But it turns out we cannot actually guarantee an exact configuration of a role using terraform, since any policies added to the role outside of terraform are basically invisible to terraform right now. That's pretty bad in our book. We'll need to use something else to manage IAM roles until this is fixed. I see it as similar functionality as what terraform provides with security groups... You can either define the rules as part of the aws_security_group resource, and those rules will remove any other rules, ensuring the exact configuration of the security group. Or you can use the aws_security_group_rule resource to add rules to a security group without removing any externally added rules. |
The only thing I'd quibble with is that using Terraform in this way doesn't create a security hole where there wasn't one before. If you consider users groups and roles that aren't managed by code to be a security hole, then it's true that Terraform doesn't fix that, but Terraform doesn't fix a lot of security holes. All that said, we of course want this feature, since this seems like a security hole that Terraform could fix. :^) (Or an "issue" that it could "address", if you like.) |
@jbscare @bflad @lorengordon I'm working on a PR for an exclusive list of role policies (
The new resource would not associate listed policies with the role. It would detach managed or delete inline policies found that weren't listed. If you didn't want the resource to mess with managed policies, you could skip the argument and the role's managed policies would be left unaffected. Same for inline policies. If you wanted to make sure that no inline and/or managed policies were put/attached to the role, you could include This would provide all the security benefits with no redundant functionality. To associate a policy with a role, you would have to use resource "aws_iam_role_policy_list" "policy_list" {
name = "yak_testing_role_policy_list"
role = "${aws_iam_role.instance_role.name}"
managed_policies = [
"${aws_iam_policy.policy_one.arn}",
"${aws_iam_policy.policy_two.arn}",
]
inline_policies = [
"${aws_iam_role_policy.inline_test_policy1.name}",
"${aws_iam_role_policy.inline_test_policy2.name}",
]
}
The same as the first approach except with the added convenience that you would not need
Redundant functionality but very convenient. You can create and associate managed and inline policies, and an exclusive list, all with the same resource. resource "aws_iam_role_policy_list" "policy_list" {
name = "yak_testing_role_policy_list"
role = "${aws_iam_role.instance_role.name}"
managed_policy {
name = "test_managed_policy"
path = "/"
description = "My test policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
inline_policy {
name = "test_inline_policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
}
I think that #2 is probably the best approach but #1 has merit. #3 is the wrong approach IMO. |
I like option 2: I think we want to be able to say "this role/user/group should have exactly this list of policies attached", and Terraform should cause that to happen, whether that means removing policies that are attached but aren't on the list, or adding policies that aren't attached and are on the list. It seems like option 1 could get you into a weird state where your TF config could define a policy attachment but not have it on the list -- what would Terraform do then? |
Terraform would first attach it, then detach it! 😂 Don't do that! Option 2 doesn't resolve that scenario for inline policies... If a user creates and associates the inline policy using Personally, I'm ok with this, as I think it would be pretty apparent what was happening from one I like option 1... I think option 3 could be compelling but only if we can reuse the code from the other modules. |
That's not a problem for managed policies. The scenario is not possible for inline. The scenarios would be:
Both option 1 and option 2 would do the same thing with inconsistent config (e.g., |
@lorengordon @jbscare @bflad Implementation of the new resource is pretty much ready. (Still working on docs and tests.) But, just to make sure we're on the same page, please consider the following config and outcomes and see if it works for you. resource "aws_iam_role_policy_list" "rpl" {
name = "yak_testing_role_policy_list"
managed_policies = [
"${aws_iam_policy.policy_one.arn}",
"${aws_iam_policy.policy_two.arn}",
]
inline_policies = [
"${aws_iam_role_policy.inline_test_policy.name}",
]
role = "${aws_iam_role.instance_role.name}"
}
resource "aws_iam_role_policy" "inline_test_policy" {
name = "yak_inline_test_policy"
role = "${aws_iam_role.instance_role.name}"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
data "aws_iam_policy_document" "instance_assume_role_policy" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "instance_role" {
name = "yak_instance_role"
path = "/system/"
assume_role_policy = "${data.aws_iam_policy_document.instance_assume_role_policy.json}"
}
resource "aws_iam_policy" "policy_one" {
name = "yak_test_policy1"
path = "/"
description = "My test policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_policy" "policy_two" {
name = "yak_test_policy2"
path = "/"
description = "My test policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:Describe*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
} Assuming, this chain of events, the table lists the outcomes.
Let me know if you'd like more tests or different outcomes. |
Just to clarify, in that table in the previous comment, the "Action" column describes what would happen if you did a If so, that all sounds good to me! One thought: I'm not sure about the Also, is this only for roles? Could it be extended to cover users and groups as well? Thanks for all your work on this! |
I'll clean up the table to make it a bit clearer.
Right now I'm just working roles. With some lessons learned with roles (with the implementation and merge process), we may have a chance to do users and groups as well. |
@jbscare @lorengordon Feel free to thumbs up the PR if you have a chance. |
The acceptance tests for PR #5904 cover the tests in the comment above. |
Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label. If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you! |
Please don't close this, it would be a very important feature for maintaining strict control over iam roles (and users and groups). |
Hi, This also makes it impossible to catch the drift, which stops the role from being deleted if force_detach_policies value is set true. I completely agree with the model shared in comment : #4426 (comment) I would appreciate if someone can share the latest update on this bug. Thanks |
If anyone subscribed here still really cares about this feature like I do, here are few new issues to please go give a thumbs up, plus the pr that implements exclusive attachment for IAM roles...
|
This provides a way to maintain an exhaustive list of policies associated with a given role. When applied, any changes made outside of Terraform, are reverted back to the configuration provided to Terraform. See hashicorp#4426
Hello! It took me a quite a while to figure out what It looks like I'm not the only person that was confused: https://discuss.hashicorp.com/t/confusion-about-aws-iam-role-managed-policy-arns-attribute/29728 Could the documentation be expanded / reworded? In particular, the usage of "exclusive" made me think that "oh, this role is the only user of this policy", not "this role is the only thing that controls which policies are attached to itself". Maybe something along the lines of:
Thank you! |
@AnthonyFoiani-at I do not believe that is accurate. When you specify this:
The |
Thank you for the correction -- I will do some experiments! Hopefully it's still a constructive message that the documentation is confusing? |
@lorengordon wrote:
Verified! Thank you for the correction. |
Nice. I think part of understanding the docs comes with the term "exclusive" and what terraform means by that. And then the tri-modal nature of assigning a value. A few resources have this concept of what I call a "container" resource and an attachment. Like IAM Roles (container) and policies (attachment), and security groups (container) and rules (attachment). "Exclusive" is in relation to how terraform manages the attachments on the container resource. When you use an attribute on the "container" resource that manages attachments, it is an "exclusive" relationship. I.e. Exactly and only these attachments should be present, and any other attachments other than what is specified will be removed. When you use a separate attachment resource, it is non-exclusive. Meaning you could have one terraform state that manages the container resource (without specifying the attachment attribute), and then you could have any number of other terraform states managing attachments to that container resource. Or really, the attachments could be created any way at all, including manually in the console or cli. When running terraform on the state that manages the container resource, it will just ignore the attachments. So, that kinda gets at the tri-modal nature also... Here is what I mean, see the comment on each example:
|
@lorengordon Those examples are great! "Tri-modal" isn't a word I hear very often. :-) And now that I [am pretty sure! I] understand what's going on, the existing wording in the docs makes sense. That's a tough puzzle to crack; hopefully my naive comments above might help us find a starting point. The only change I'd suggest is to the last one:
Thank you all again, and have a great weekend! |
As of Inline policies: Customer managed policy attachments:
The following proposal contains more context for the creation of these resources, and this meta issue tracks the progress of "exclusive relationship management resources" across the entire provider. With the availability of these resources, this issue can now be closed. |
Warning This issue has been closed, meaning that any additional comments are hard for our team to see. Please assume that the maintainers will not see them. Ongoing conversations amongst community members are welcome, however, the issue will be locked after 30 days. Moving conversations to another venue, such as the AWS Provider forum, is recommended. If you have additional concerns, please open a new issue, referencing this one where needed. |
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. |
Terraform Version
Affected Resource(s)
Expected Behavior
This is a feature request for either (a) an enhancement to aws_iam_user_policy_attachment, aws_iam_group_policy_attachment, and aws_iam_role_policy_attachment; or (b) to create a new trio of resources (perhaps aws_iam_user_policy_list, aws_iam_group_policy_list, and aws_iam_role_policy_list?), to allow for the specification of an exclusive list of policies that should be attached to a group or role, much like aws_iam_group_membership allows for the specification of an exclusive list of users who should be members of a group. If any policies are found attached to the group or role that aren't on the list, they should be removed.
Actual Behavior
There doesn't seem to be a way to accomplish this effect at this time. (You can get sort of a converse of this effect with aws_iam_policy_attachment, which specifies an exclusive list of roles and users and groups to which a policy is attached, but doesn't exclude other policies from being attached to a role, user, or group.)
Use case
We'd like to use Terraform to fully specify the policies that should be attached to a user or group or role, and if someone adds a policy outside of Terraform, for Terraform to detect and correct that.
The text was updated successfully, but these errors were encountered: