我的 Amazon S3 存储桶具有默认的使用自定义 AWS KMS 密钥的加密。我如何允许用户从存储桶下载和上传到存储桶?

上次更新日期:2020 年 10 月 20 日

我已将 Amazon Simple Storage Service (Amazon S3) 存储桶设置为使用默认的 AWS Key Management Service (AWS KMS) 密钥加密。我希望 AWS Identity and Access Management (IAM) 用户可以从存储桶下载和上传到存储桶。该如何操作?

解决方法

IAM 用户和 AWS KMS 密钥属于同一 AWS 账户

1.    打开 AWS KMS 控制台,然后使用策略视图查看密钥的策略文档。修改密钥的策略,以至少授予用户 kms:Encryptkms:GenerateDataKeykms:Decrypt 操作的权限。您可以使用类似于以下的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey"
      ],
      "Effect": "Allow",
      "Principal": [
        "AWS": "arn:aws:iam::111122223333:user/Jane"
      ],
      "Resource": "*"
    }
  ]
}

注意:此示例策略仅包括单个 IAM 用户下载和上传至加密 S3 存储桶所需的最低权限。您可以根据您的使用案例修改或扩展权限。 

2.    打开 IAM 控制台向该 IAM 用户添加一个策略,以授予在该存储桶上执行上传和下载操作的权限。您可以使用类似于以下的策略:

注意:对于 Resource 值,请输入存储桶的 Amazon 资源名称 (ARN),用通配符来表示存储桶中的对象。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
    }
  ]
}

重要提示:IAM 用户策略授予的 S3 权限可能会被存储桶策略中的显式拒绝语句阻止。请务必检查存储桶策略,以确认不存在任何与该 IAM 用户策略冲突的显式拒绝语句。

IAM 用户与 AWS KMS 密钥和 S3 存储桶位于不同的账户中

重要提示:您可以为客户托管的 AWS KMS 密钥而不是 AWS 托管的 AWS KMS 密钥授予跨账户访问权限。无法修改 AWS 托管的 AWS KMS 密钥的密钥策略。 

1.    打开 AWS KMS 控制台,然后使用策略视图查看密钥的策略文档。修改密钥的策略,以至少授予用户 kms:Encryptkms:GenerateDataKeykms:Decrypt 操作的权限。您可以使用类似于以下的策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey"
      ],
      "Effect": "Allow",
      "Principal": [
        "AWS": "arn:aws:iam::111122223333:user/Jane"
      ],
      "Resource": "*"
    }
  ]
}

注意:此示例策略仅包括单个 IAM 用户下载和上传至加密 S3 存储桶所需的最低权限。您可以根据您的使用案例修改或扩展权限。

2.    从 IAM 用户所属的账户打开 IAM 控制台向该 IAM 用户添加一个策略,以授予在该存储桶上执行上传和下载操作以及使用与该存储桶关联的 AWS KMS 密钥的权限。

对于跨账户情景,请考虑授予 s3:PutObjectAcl 权限,以确保该 IAM 用户可以上传对象,然后向该存储桶的账户授予对该对象的完全控制权限 (bucket-owner-full-control)。此外还应考虑授予授予 s3:ListBucket 权限,因为运行 同步操作递归复制操作将需要此权限。您可以使用类似于以下的策略:

注意:对于第一个 Resource 的值,请输入存储桶的 ARN,用通配符来表示存储桶中的对象。对于第二个 Resource 值,请输入存储桶的 ARN。对于第三个 Resource 值,请输入该 AWS KMS 密钥的 ARN。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DownloadandUpload",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET"
    },
    {
      "Sid": "KMSAccess",
      "Action": [
        "kms:Decrypt",
        "kms:Encrypt",
        "kms:GenerateDataKey"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:kms:example-region-1:123456789098:key/111aa2bb-333c-4d44-5555-a111bb2c33dd"
    }
  ]
}

3.    从拥有该 S3 存储桶的账户打开 Amazon S3 控制台更新存储桶策略以向该 IAM 用户授予对该存储桶的访问权限。您可以使用类似于以下的策略:

注意:对于 Principal 值,请输入 IAM 用户的 ARN。对于第一个 Resource 值,请输入存储桶的 ARN,用通配符来表示存储桶中的对象。对于第二个 Resource 值,请输入存储桶的 ARN。

{
  "Id": "Policy1584399307003",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DownloadandUpload",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Jane"
        ]
      }
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Jane"
        ]
      }
    }
  ]
}