0

Is there any way in AWS policies to enforce that, when someone creates a role, that its policies have a condition (e.g. only accessing resources with a certain tag)?

like "you can create any resource, and any role/etc to act on things, so long as they have a tag XXX"

So people could make things at their leisure, but not be able to make things that access stuff that doesn't have their tag. A kind of pseudo sandboxing.

Would this be something like

{
  "Sid": "AllowUserToAttachRolePolicy",
  "Effect": "Allow",
  "Action": "iam:AttachRolePolicy",
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:RequestTag/CreatedBy": "username_as_tag_value"
    }
  }
}

is this sufficient? Or is there more?

New Alexandria
  • 6,951
  • 4
  • 57
  • 77
  • 1
    Take a look at [IAM condition boundaries](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html). – jarmod May 18 '23 at 23:49
  • You might also find some use in [Organizations tag policies](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_tag-policies.html). – user3553031 May 19 '23 at 02:00

1 Answers1

0

I found an answer to this. I think the following policy is not well-tuned, and may miss certain edge cases.

It did work for what I need - albeit not yet robustly for a 'do anything' sandbox. I'm posting it so it might help others.

If anyone develops a complete answer, I'd be glad to accept theirs

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "I can tag myself",
      "Effect": "Allow",
      "Action": "ec2:CreateTags",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "create and tag my roles",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:TagRole"
      ],
      "Resource": "arn:aws:iam::*:role/*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "AllowDescribeRoles",
      "Effect": "Allow",
      "Action": [
        "iam:ListRoles",
        "iam:ListRoleTags"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowDescribeTaggedRoles",
      "Effect": "Allow",
      "Action": "iam:GetRole",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "AllowAttachRolePolicy",
      "Effect": "Allow",
      "Action": "iam:AttachRolePolicy",
      "Resource": "arn:aws:iam::*:role/*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "ServiceLinkedRoles to my RDS",
      "Effect": "Allow",
      "Action": "iam:CreateServiceLinkedRole",
      "Resource": "arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS",
      "Condition": {
        "StringLike": {
          "iam:AWSServiceName": "redshift.amazonaws.com"
        },
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "ServiceLinkedRoles to my RDS",
      "Effect": "Allow",
      "Action": "iam:CreateServiceLinkedRole",
      "Resource": "arn:aws:iam::*:role/aws-service-role/rds.amazonaws.com/AWSServiceRoleForRDS",
      "Condition": {
        "StringLike": {
          "iam:AWSServiceName": "rds.amazonaws.com"
        },
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "View and Change Own Policies",
      "Effect": "Allow",
      "Action": [
        "iam:ListPolicies",
        "iam:ListPolicyTags",
        "iam:GetPolicy",
        "iam:TagPolicy",
        "iam:CreatePolicy",
        "iam:CreatePolicyVersion",
        "iam:DeletePolicy",
        "iam:UpdateAssumeRolePolicy",
        "iam:AttachUserPolicy",
        "iam:AttachRolePolicy",
        "iam:ListAttachedRolePolicies",
        "iam:ListRolePolicies",
        "iam:GetRolePolicy",
        "access-analyzer:*Policy*"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "organizations:DescribeAccount",
        "organizations:DescribeOrganization"
      ],
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "aws:PrincipalArn": "arn:aws:iam::*:user/${aws:username}"
        }
      }
    },
    {
      "Sid": "create my own RDS",
      "Effect": "Allow",
      "Action": [
        "rds:*",
        "rds:DescribeDBEngineVersions",
        "rds:DescribeOrderableDBInstanceOptions",
        "rds:CreateDBInstance",
        "rds:CreateDBCluster"
      ],
      "Resource": [
        "arn:aws:iam::*:role/AWSReservedSSO_*",
        "arn:aws:rds:*:*:db:*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "Allow my S3",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "No STS on Prod",
      "Effect": "Allow",
      "Action": [
        "sts:AssumeRole",
        "sts:TagSession"
      ],
      "Resource": [
        "arn:aws:rds:*:*:db*",
        "arn:aws:s3:::*"
      ],
      "Condition": {
        "ForAnyValue:StringNotEquals": {
          "aws:RequestTag/environment": "prod"
        }
      }
    },
    {
      "Sid": "AllowUserTagSandboxedDatabaseAdministratorAccess",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole",
        "rds:*"
      ],
      "Resource": [
        "arn:aws:iam::*:role/AWSReservedSSO_*",
        "arn:aws:rds:*:*:db:*",
        "arn:aws:rds:*:*:*:*"
      ]
    },
    {
      "Sid": "AllowUserTagSandboxedDatabaseAdministratorResources",
      "Effect": "Allow",
      "Action": [
        "rds:*",
        "secretsmanager:*",
        "kms:*",
        "cloudwatch:GetMetricStatistics",
        "cloudwatch:DescribeAlarms",
        "cloudwatch:ListMetrics",
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:DescribeLogStreams",
        "logs:PutLogEvents",
        "logs:PutMetricFilter",
        "logs:PutRetentionPolicy",
        "logs:TestMetricFilter",
        "sns:Publish",
        "sns:ListTopics",
        "sns:ListSubscriptionsByTopic"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "AllowUserTagSandboxedDescribeClusters",
      "Effect": "Allow",
      "Action": [
        "rds:DescribeDBInstances",
        "rds:DescribeDBClusters",
        "rds:DescribeGlobalClusters"
      ],
      "Resource": [
        "arn:aws:rds:*:*:db:*",
        "arn:aws:rds:*:*:cluster:*",
        "arn:aws:rds::*:global-cluster:*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "RedshiftCreate",
      "Effect": "Allow",
      "Action": [
        "redshift-serverless:*",
        "redshift:*",
        "sqlworkbench:*"
      ],
      "Resource": [
        "arn:aws:redshift:*:*:*:*",
        "arn:aws:redshift-serverless:*:*:*:*",
        "arn:aws:sqlworkbench:*:*:*:*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/CreatedByUser": "${aws:username}"
        }
      }
    },
    {
      "Sid": "semi-excessive list/get actions group",
      "Effect": "Allow",
      "Action": [
        "iam:List*",
        "iam:Get*",
        "iam:SimulatePrincipalPolicy",
        "iam:SimulateCustomPolicy"
      ],
      "Resource": "*"
    }
  ]
}
New Alexandria
  • 6,951
  • 4
  • 57
  • 77