Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MalformedPolicy error using aws s3api

I am trying to use put-bucket-policy to add a policy to an s3 bucket via the aws s3api (Windows).

I am using precisely the policy code given here http://docs.aws.amazon.com/AmazonS3/latest/dev/AccessPolicyLanguage_UseCases_s3_a.html under "Granting Permission to an Anonymous User" with my bucket name substituted in.

I am getting

A client error (MalformedPolicy) occured: policies must be valid JSON and the first byte must be '{'

Any clues?

EDIT: Inlining the JSON works- so it is some kind of file format issue - just not one that I can see. Be great to be able to get it working with files.

EDIT: To help anyone else who maybe ends up here, buckets should be named all in lowercase. If not, some s3/s3api operations work, but not others. See here

like image 617
kpollock Avatar asked Oct 21 '13 14:10

kpollock


1 Answers

TL;DR


You must add file:// protocol scheme to the policy file path

$ aws s3api put-bucket-policy --bucket kryptonite \
   --policy file:///home/superman/aws-example/public-bucket-policy.json


OR (Windows)


$ aws s3api put-bucket-policy --bucket kryptonite \
   --policy file://C:\Temp\public-bucket-policy.json


OR (relative path)


$ aws s3api put-bucket-policy --bucket kryptonite \
   --policy file://public-bucket-policy.json


FULL STORY: How to set public bucket policy via CLI

First let's make sure there's no other policy on the bucket:

$ s3api get-bucket-policy --bucket kryptonite

A client error (NoSuchBucketPolicy) occurred when calling the   GetBucketPolicy
   operation: The bucket policy does not exist


Now let's make sure we have policy file in current directory and it contains valid json (mind name of the kryptonite bucket

$ ls
public-bucket-policy.json

$ cat public-bucket-policy.json 
{
  "Statement": [
    {
      "Resource": "arn:aws:s3:::kryptonite/*",
      "Action": "s3:GetObject",
      "Principal": "*",
      "Effect": "Allow",
      "Sid": "AddPerm"
    }
  ],
  "Version": "2012-10-17"
}


Now let's try to put the policy by specifying just filename

$ s3api put-bucket-policy --bucket kryptonite --policy public-bucket-policy.json

A client error (MalformedPolicy) occurred when calling the PutBucketPolicy 
   operation: Policies must be valid JSON and the first byte must be '{'


Now let's make another attempt and specify the full path $ s3api put-bucket-policy --bucket kryptonite \ --policy /home/superman/aws-example/public-bucket-policy.json

A client error (MalformedPolicy) occurred when calling the PutBucketPolicy 
   operation: Policies must be valid JSON and the first byte must be '{'


Now let's add file:// prefix and it will work

$ s3api put-bucket-policy --bucket kryptonite \
    --policy file:///home/superman/aws-example/public-bucket-policy.json


And we can now verify that this policy had been applied

$ s3api get-bucket-policy --bucket kryptonite
{
    "Policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AddPerm\",\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"s3:GetObject\",\"Resource\":\"arn:aws:s3:::kryptonite/*\"}]}"
}


And as special bonus let's pipe the policy through the jq utility (twice) to extract correct field and format JSON nicely

$ s3api get-bucket-policy --bucket kryptonite | jq .Policy --raw-output | jq .
{
  "Statement": [
    {
      "Resource": "arn:aws:s3:::kryptonite/*",
      "Action": "s3:GetObject",
      "Principal": "*",
      "Effect": "Allow",
      "Sid": "AddPerm"
    }
  ],
  "Version": "2012-10-17"
}


And as you can see the policy is correct

like image 158
Dimitry K Avatar answered Nov 10 '22 20:11

Dimitry K