SunSparc
SunSparc

Reputation: 1922

S3 bucket policy: In a Public Bucket, make a sub-folder private

I have a bucket filled with contents that need to be mostly public. However, there is one folder (aka "prefix") that should only be accessible by an authenticated IAM user.

{
  "Statement": [
    {
      "Sid": "AllowIAMUser",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/prefix1/prefix2/private/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/bobbydroptables"
        ]
      }
    },
    {
      "Sid": "AllowAccessToAllExceptPrivate",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::bucket/*",
      "Condition": {
        "StringNotLike": {
          "s3:prefix": "prefix1/prefix2/private/"
        }
      },
      "Principal": {
        "AWS": [
          "*"
        ]
      }
    }
  ]
}

When I try to save this policy I get the following error messages from AWS:

Conditions do not apply to combination of actions and resources in statement -
  Condition "s3:prefix"
  and action "s3:GetObject"
  in statement "AllowAccessToAllExceptPrivate"

Obviously this error applies specifically to the second statement. Is it not possible to use the "s3:prefix" condition with the "s3:GetObject" action?

Is it possible to take one portion of a public bucket and make it accessible only to authenticated users?

In case it matters, this bucket will only be accessed read-only via api.

This question is similar to Amazon S3 bucket policy for public restrictions only, except I am trying to solve the problem by taking a different approach.

Upvotes: 10

Views: 7403

Answers (1)

SunSparc
SunSparc

Reputation: 1922

After much digging through AWS documentation, as well as many trial and error permutations in the policy editor, I think I have found an adequate solution.

Apparently, AWS provides an option called NotResource (not found in the Policy Generator currently).

The NotResource element lets you grant or deny access to all but a few
of your resources, by allowing you to specify only those resources to
which your policy should not be applied.

With this, I do not even need to play around with conditions. This means that the following statement will work in a bucket policy:

{
  "Sid": "AllowAccessToAllExceptPrivate",
  "Action": [
    "s3:GetObject",
    "s3:GetObjectVersion"
  ],
  "Effect": "Allow",
  "NotResource": [
    "arn:aws:s3:::bucket/prefix1/prefix2/private/*",
    "arn:aws:s3:::bucket/prefix1/prefix2/private"
  ],
  "Principal": {
    "AWS": [
      "*"
    ]
  }
}

Upvotes: 27

Related Questions