Skip to content
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

feat: Add support for roles created to explicitly assume their own role if desired #281

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions examples/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ provider "aws" {
module "iam_assumable_role_admin" {
source = "../../modules/iam-assumable-role"

# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
allow_self_assume_role = true

trusted_role_arns = [
"arn:aws:iam::307990089504:root",
"arn:aws:iam::835367859851:user/anton",
Expand Down Expand Up @@ -127,16 +130,6 @@ data "aws_iam_policy_document" "custom_trust_policy" {
identifiers = ["*"]
}
}

statement {
effect = "Deny"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:aws:iam::111111111111:root"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when testing the example, this failed due to the account ID (I assume) so I removed

}
}
}

#########################################
Expand Down
1 change: 1 addition & 0 deletions modules/iam-assumable-role-with-oidc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS account ID where the OIDC provider lives, leave empty to use the account for the AWS provider | `string` | `""` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `false` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
20 changes: 17 additions & 3 deletions modules/iam-assumable-role-with-oidc/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,32 @@ locals {
}

data "aws_caller_identity" "current" {}

data "aws_partition" "current" {}

data "aws_iam_policy_document" "assume_role_with_oidc" {
count = var.create_role ? 1 : 0

dynamic "statement" {
for_each = local.urls
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
effect = "Allow"
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

dynamic "statement" {
for_each = local.urls

content {
effect = "Allow"
actions = ["sts:AssumeRoleWithWebIdentity"]

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role-with-oidc/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,9 @@ variable "force_detach_policies" {
type = bool
default = false
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-role-with-saml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ No modules.
|------|------|
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role_with_saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_saml_endpoint"></a> [aws\_saml\_endpoint](#input\_aws\_saml\_endpoint) | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `false` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
22 changes: 20 additions & 2 deletions modules/iam-assumable-role-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
identifiers = compact(distinct(concat(var.provider_ids, [var.provider_id])))
number_of_role_policy_arns = coalesce(var.number_of_role_policy_arns, length(var.role_policy_arns))
}

data "aws_iam_policy_document" "assume_role_with_saml" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRoleWithSAML"]

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role-with-saml/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,9 @@ variable "force_detach_policies" {
type = bool
default = false
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ No modules.
| [aws_iam_role_policy_attachment.custom](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.assume_role_with_mfa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_admin_role_policy_arn"></a> [admin\_role\_policy\_arn](#input\_admin\_role\_policy\_arn) | Policy ARN to use for admin role | `string` | `"arn:aws:iam::aws:policy/AdministratorAccess"` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_attach_admin_policy"></a> [attach\_admin\_policy](#input\_attach\_admin\_policy) | Whether to attach an admin policy to a role | `bool` | `false` | no |
| <a name="input_attach_poweruser_policy"></a> [attach\_poweruser\_policy](#input\_attach\_poweruser\_policy) | Whether to attach a poweruser policy to a role | `bool` | `false` | no |
| <a name="input_attach_readonly_policy"></a> [attach\_readonly\_policy](#input\_attach\_readonly\_policy) | Whether to attach a readonly policy to a role | `bool` | `false` | no |
Expand Down
41 changes: 37 additions & 4 deletions modules/iam-assumable-role/main.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
role_sts_externalid = flatten([var.role_sts_externalid])
}

data "aws_iam_policy_document" "assume_role" {
count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 0 : 1

statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = var.trusted_role_actions

principals {
Expand All @@ -34,9 +52,24 @@ data "aws_iam_policy_document" "assume_role" {
data "aws_iam_policy_document" "assume_role_with_mfa" {
count = var.custom_role_trust_policy == "" && var.role_requires_mfa ? 1 : 0

statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = var.trusted_role_actions

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-role/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,9 @@ variable "role_sts_externalid" {
type = any
default = []
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}
3 changes: 3 additions & 0 deletions modules/iam-assumable-roles-with-saml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ No modules.
| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role_with_saml](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

Expand All @@ -45,6 +47,7 @@ No modules.
| <a name="input_admin_role_permissions_boundary_arn"></a> [admin\_role\_permissions\_boundary\_arn](#input\_admin\_role\_permissions\_boundary\_arn) | Permissions boundary ARN to use for admin role | `string` | `""` | no |
| <a name="input_admin_role_policy_arns"></a> [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` | <pre>[<br> "arn:aws:iam::aws:policy/AdministratorAccess"<br>]</pre> | no |
| <a name="input_admin_role_tags"></a> [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_aws_saml_endpoint"></a> [aws\_saml\_endpoint](#input\_aws\_saml\_endpoint) | AWS SAML Endpoint | `string` | `"https://signin.aws.amazon.com/saml"` | no |
| <a name="input_create_admin_role"></a> [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no |
| <a name="input_create_poweruser_role"></a> [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no |
Expand Down
19 changes: 19 additions & 0 deletions modules/iam-assumable-roles-with-saml/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

locals {
identifiers = compact(distinct(concat(var.provider_ids, [var.provider_id])))
}

data "aws_iam_policy_document" "assume_role_with_saml" {
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"

Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-roles-with-saml/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ variable "aws_saml_endpoint" {
type = string
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}

# Admin
variable "create_admin_role" {
description = "Whether to create admin role"
Expand Down
3 changes: 3 additions & 0 deletions modules/iam-assumable-roles/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ No modules.
| [aws_iam_role_policy_attachment.admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.poweruser](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.readonly](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.assume_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.assume_role_with_mfa](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |

## Inputs

Expand All @@ -45,6 +47,7 @@ No modules.
| <a name="input_admin_role_policy_arns"></a> [admin\_role\_policy\_arns](#input\_admin\_role\_policy\_arns) | List of policy ARNs to use for admin role | `list(string)` | <pre>[<br> "arn:aws:iam::aws:policy/AdministratorAccess"<br>]</pre> | no |
| <a name="input_admin_role_requires_mfa"></a> [admin\_role\_requires\_mfa](#input\_admin\_role\_requires\_mfa) | Whether admin role requires MFA | `bool` | `true` | no |
| <a name="input_admin_role_tags"></a> [admin\_role\_tags](#input\_admin\_role\_tags) | A map of tags to add to admin role resource. | `map(string)` | `{}` | no |
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_create_admin_role"></a> [create\_admin\_role](#input\_create\_admin\_role) | Whether to create admin role | `bool` | `false` | no |
| <a name="input_create_poweruser_role"></a> [create\_poweruser\_role](#input\_create\_poweruser\_role) | Whether to create poweruser role | `bool` | `false` | no |
| <a name="input_create_readonly_role"></a> [create\_readonly\_role](#input\_create\_readonly\_role) | Whether to create readonly role | `bool` | `false` | no |
Expand Down
41 changes: 37 additions & 4 deletions modules/iam-assumable-roles/main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
data "aws_caller_identity" "current" {}
data "aws_partition" "current" {}

data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
Expand All @@ -17,9 +35,24 @@ data "aws_iam_policy_document" "assume_role" {
}

data "aws_iam_policy_document" "assume_role_with_mfa" {
statement {
effect = "Allow"
dynamic "statement" {
# https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/
for_each = var.allow_self_assume_role ? [1] : []

content {
sid = "ExplicitSelfRoleAssumption"
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
type = "AWS"
identifiers = ["arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:role${var.role_path}${var.role_name}"]
}
}
}

statement {
effect = "Allow"
actions = ["sts:AssumeRole"]

principals {
Expand Down
6 changes: 6 additions & 0 deletions modules/iam-assumable-roles/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ variable "mfa_age" {
default = 86400
}

variable "allow_self_assume_role" {
description = "Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/)"
type = bool
default = false
}

# Admin
variable "create_admin_role" {
description = "Whether to create admin role"
Expand Down
1 change: 1 addition & 0 deletions modules/iam-eks-role/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_allow_self_assume_role"></a> [allow\_self\_assume\_role](#input\_allow\_self\_assume\_role) | Determines whether to allow the role to be [assume itself](https://aws.amazon.com/blogs/security/announcing-an-update-to-iam-role-trust-policy-behavior/) | `bool` | `false` | no |
| <a name="input_cluster_service_accounts"></a> [cluster\_service\_accounts](#input\_cluster\_service\_accounts) | EKS cluster and k8s ServiceAccount pairs. Each EKS cluster can have multiple k8s ServiceAccount. See README for details | `map(list(string))` | `{}` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Whether to create a role | `bool` | `true` | no |
| <a name="input_force_detach_policies"></a> [force\_detach\_policies](#input\_force\_detach\_policies) | Whether policies should be detached from this role when destroying | `bool` | `false` | no |
Expand Down
Loading