0
votes

I'll like my Iam policy used for a cross account to access just a single S3 bucket as in the example below but it fails with permission denied. The failure occurs when i switch to a cross account role on the console in AccountA and attempt to access the S3 bucket in accountB. However, I am able to view the S3 bucket in accountB when I change the "Resource" on the Iam policy to allow everything.

xx.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "mysid",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::mybucket/*",
        "arn:aws:s3:::mybucket/"
      ]
    }
  ]
}

However, I am able to view the S3 bucket in accountB when I change the "Resource" on the Iam policy to allow everything. eg

xxx.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "mysid",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "*"
      ]
    }
  ]
}

but this is not what i want.

other files used include:

xx.tpl

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "${Sid}",
            "Effect": "${Effect}",
            "Action": "${Action}",
            "Resource": "${Resource}"
        }
    ]
}

xx.tf

data "aws_iam_policy_document" "s3_write" {
  count         = length(var.s3_bucket_names)

  statement {
    actions   = ["s3:PutObject", "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:PutObjectAcl", "s3:List*", "s3:Get*", "s3:*"]
    resources = ["arn:aws:s3:::${aws_s3_bucket.mybucket[count.index].id}/*", "arn:aws:s3:::${aws_s3_bucket.mybucket[count.index].id}"]
    principals {
      identifiers = var.principals
      type        = "AWS"
    }
  }


resource "aws_s3_bucket_policy" "s3_lb" {
  count         = length(var.s3_bucket_names)
  bucket = aws_s3_bucket.mybucket[count.index].id
  policy = data.aws_iam_policy_document.s3_write[count.index].json
}

s3 bucket policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::xxxx:role/test-role1",
                    "arn:aws:iam::xxxx:role/test-role2",
                    "arn:aws:iam::xxxx:role/test-role3",
                    "arn:aws:iam::xxxx-other:role/s3-list-role"
                ]
            },
            "Action": [
                "s3:PutObjectAcl",
                "s3:PutObject",
                "s3:List*",
                "s3:Get*",
                "s3:DeleteObjectVersion",
                "s3:DeleteObject",
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket/*",
                "arn:aws:s3:::mybucket"
            ]
        }
    ]
}
2
What do you mean by "restrict my Iam policy used for a cross account role to a single S3 bucket"? How is the IAM Role used? What command are you using when it fails? What are you wanting it to be able to do / not do? Please edit your question to add these details instead of replying in a comment. - John Rotenstein
Your first IAM policy has arn:aws:s3:::mybucket/* and then arn:aws:s3:::mybucket/. The last one doesn't want a trailing slash. - ydaetskcoR
@ydaetskcoR I've removed trailing slash and still have the error - manoman687
Can you provide the actual IAM policy attached to the cross-account role & the S3 bucket policy? You can change the bucket names in the policies. - Harish KM
S3 bucket policy - manoman687

2 Answers

1
votes

I changed this:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "mysid",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::mybucket/*",
        "arn:aws:s3:::mybucket/"
      ]
    }
  ]
}

To this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket/*"
            ]
        }
    ]
}

Giving my IAM user cross account access to both the console and CLI. The first allow statement is required for console cross account access.

0
votes

If arn:aws:iam::xxxx:role/test-role1 has this policy attached, then a session with that role will get access to the bucket:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "mysid",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::mybucket/*",
        "arn:aws:s3:::mybucket"
      ]
    }
  ]
}

The S3 bucket policy grants this principal access. The problem is the trailing slash on the bucket ARN (second resource listed in the policy above.