首页 > 解决方案 > How do I write an AWS IAM policy that grants read access to everyone else's buckets?

问题描述

I'm writing an IAM policy for my Kubernetes workers. I want them to have read/write access to a certain S3 bucket, no access to other S3 buckets in my account, but read access to any bucket that is publicly readable (such as the s3://1000genomes/ bucket, and other buckets where Amazon or other people have put up public data).

(Whether access is granted or denied to public buckets in my account doesn't matter. If I need to grant access to one I can do that explicitly. But I can't go granting access to every public bucket in the world explicitly.)

I can write a stanza that looks like this to give read access to all buckets in the world:

    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::*",
        "arn:aws:s3:::*/*"
      ]
    }

I can also write one that grants access to the particular named bucket on my account that I want to allow access to, filling the name in for *.

But how do I write a policy that denies access to buckets on my account that aren't the named bucket? Or if I take a different approach, how do I write a grant for all buckets not on my account? Is there something I can put between those extra colons that will do this? I've tried using Resource and NotResource together, but AWS rejects that.

For reference, my policy looks like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::vg-k8s",
                "arn:aws:s3:::vg-k8s/*",
            ]
        }
    ]
}

With that policy in place on my nodes' group, I have no access to s3://1000genomes from the nodes. To get access to that bucket specifically, I can change it to:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": "arn:aws:s3:::*"
        },
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::vg-k8s",
                "arn:aws:s3:::vg-k8s/*",
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::1000genomes",
                "arn:aws:s3:::1000genomes/*"
            ]
        }
    ]
}

But I need a way to do this so I cover all public buckets, not just those I list, but so I don't cover non-public buckets in my account.

标签: amazon-web-servicesamazon-s3amazon-iam

解决方案


如何编写拒绝访问我账户上不是命名存储桶的存储桶的策略?

你没有。默认情况下拒绝 IAM 策略。

如何授予对任何公开可读的存储桶的读取权限?

你没有。访问公共存储桶不需要额外的权限或策略。

但是,您可能会在访问公共存储桶时遇到问题,并且应该将您的请求发送到公共存储桶unsigned

要从 awscli 与公共存储桶交互,请使用:

aws s3 ls s3://1000genomes/ --no-sign-request

要从 boto3 执行相同操作,请使用:

import boto3
from botocore import UNSIGNED
from botocore.config import Config
s3 = boto3.client('s3', config=Config(signature_version=UNSIGNED))

推荐阅读