Home > database >  Allow User to Only Upload to one S3 Bucket
Allow User to Only Upload to one S3 Bucket

Time:12-02

I have looked at other, similar, questions, but I can't see how to do this.

I have an S3 Bucket with all public access blocked and the bucket has serverside encryption turned on.

I want to create a user group with permissions that allow a specific user to see the bucket listed (but no others) and upload, but not download, delete, or anything else within that bucket.

I have a User Group which has permissions like so:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:CreateAccessPoint",
                "s3:PutAnalyticsConfiguration",
                "s3:PutAccelerateConfiguration",
                "s3:PutAccessPointConfigurationForObjectLambda",
                "s3:DeleteObjectVersion",
                "s3:RestoreObject",
                "s3:DeleteAccessPoint",
                "s3:CreateBucket",
                "s3:ListBucket",
                "s3:DeleteAccessPointForObjectLambda",
                "s3:ReplicateObject",
                "s3:PutEncryptionConfiguration",
                "s3:DeleteBucketWebsite",
                "s3:AbortMultipartUpload",
                "s3:PutLifecycleConfiguration",
                "s3:UpdateJobPriority",
                "s3:CreateMultiRegionAccessPoint",
                "s3:PutBucketVersioning",
                "s3:PutObjectAcl",
                "s3:PutIntelligentTieringConfiguration",
                "s3:PutMetricsConfiguration",
                "s3:PutBucketOwnershipControls",
                "s3:PutReplicationConfiguration",
                "s3:DeleteMultiRegionAccessPoint",
                "s3:PutObjectLegalHold",
                "s3:UpdateJobStatus",
                "s3:PutBucketCORS",
                "s3:PutInventoryConfiguration",
                "s3:PutObject",
                "s3:PutBucketNotification",
                "s3:DeleteStorageLensConfiguration",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutObjectRetention",
                "s3:PutBucketLogging",
                "s3:CreateAccessPointForObjectLambda",
                "s3:PutBucketObjectLockConfiguration",
                "s3:ReplicateDelete"
            ],
            "Resource": "arn:aws:s3:::my-bucket"
        }
    ]
}

I created it with the Visual Editor and it seems like overkill to me, yet, even tho I have assigned the User to that User Group, I still cannot upload a file to that Bucket or see the Bucket listed once signed in as that User.

What am I doing wrong?

///EDIT///

This is my latest version - I can see the bucket and files listed in the bucket, but not upload:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:DeleteObject",
                "s3:GetAccountPublicAccessBlock",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketAcl",
                "s3:ListAccessPoints"
            ],
            "Resource": "arn:aws:s3:::my-bucket"
        }
    ]
}

CodePudding user response:

There are a few issues here:

  1. you are mixing bucket-level and object-level actions
  2. you are using incorrect resource ARNs in some cases
  3. your policy is significantly over-permissive

The issue with actions is that some actions relate to buckets, some actions relate to objects, and other actions don't relate to a resource type at all. Any time you include both a bucket ARN (such as "arn:aws:s3:::my-bucket" or "arn:aws:s3:::*") and an object ARN (such as "arn:aws:s3:::my-bucket/*") in the same resource statement, you are probably doing it wrong.

You can see examples of bucket and object operations and you can see a list of actions defined by S3 with corresponding resource types for which those actions are relevant. Your policy should apply bucket actions to bucket resource ARNs and object actions to object resource ARNs, and they should ideally not be mixed (largely as you have done in your edited example, actually, which is good). Yes, it's tempting to do things like allow "s3:Get*" against both a bucket ARN and a wildcard object ARN, but it's not correct and it's a maintenance headache.

You will see, for example that ListAccessPoints has no associated resource type. You have indicated "arn:aws:s3:::*" which is incorrect and will grant nothing (it needs instead to be "*"). Why does it need to be "*"? Per the documentation:

If an action does not support resource-level permissions, then that statement in the policy must use a wildcard (*) in the Resource element.

This is a little unfortunate and a questionable choice on the part of AWS, in my opinion.

If you want an IAM policy that permits listing all buckets, listing objects within a specific bucket, and uploading to that same bucket, but nothing else, then I would start with:

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

Now, you might find in practice that this is insufficient and have to add additional actions (I don't know what your clients do) but it's a good place to start from, I hope.

CodePudding user response:

The issue was that some permissions only apply to non-specific resources

Here is the json for a config that I believe, works. If people look at it and notice something wrong, please comment and tell me - I have only just started with AWS!

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListAllMyBuckets",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:PutObject",
                "s3:GetObjectAcl",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:DeleteObject",
                "s3:GetBucketAcl",
                "s3:GetBucketLocation",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAccessPoints"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}
  • Related