S3 modify bucket policy using boto/boto3

0

Hi Team, Need help, was looking for a way to modify S3 bucket policy with Lambda (Python3.10) trigger. Since there is no update bucket policy is possible I was looking for option by which I can fetch existing bucket policy then modify that and put the bucket policy back. I was trying the below code but that did not help...

`#s3_client = boto3.client('s3')

bucket_name = 'vpc-flow-log-sudsark'

def lambda_handler(event, context):

# Or use client to get Bucket policy
s3_client = boto3.client('s3')
policy = s3_client.get_bucket_policy(Bucket='vpc-flow-log-sudsark')

# assign policy using s3 resource 
user_policy = {
        "Sid": "AutomatedRestrictiveAccess",
        "Effect": "Allow",
        "Principal": {
            "Service": "delivery.logs.amazonaws.com"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::vpc-flow-log-sudsark/*",
        "Condition": {
            "StringEquals": {
                "s3:x-amz-acl": "bucket-owner-full-control",
                "aws:SourceAccount": "333344445555"
            }
        }
    }
new_policy =  policy['Statement'].append(user_policy)
s3_client.put_bucket_policy(Policy=new_policy)

`

gefragt vor 2 Monaten302 Aufrufe
1 Antwort
0

Hello.

I modified the Lambda code as below.
There are a few changes, but "get_bucket_policy()" does not directly retrieve the bucket policy in json, so it is necessary to retrieve only the bucket policy part from the response.
The response looks like this:

{'ResponseMetadata': {'RequestId': 'TTTTTTTTTT', 'HostId': 'TTTTTTTTTTTTTT=', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amz-id-2': 'TTTTTTTTTTT=', 'x-amz-request-id': 'TTTTTTTTTTTT', 'date': 'Sat, 09 Mar 2024 05:58:03 GMT', 'content-type': 'application/json', 'transfer-encoding': 'chunked', 'server': 'AmazonS3'}, 'RetryAttempts': 0}, 'Policy': '{"Version":"2012-10-17","Statement":[{"Sid":"AWSLogDeliveryAclCheck","Effect":"Allow","Principal":{"Service":"delivery.logs.amazonaws.com"},"Action":"s3:GetBucketAcl","Resource":"arn:aws:s3:::test-s3","Condition":{"StringEquals":{"aws:SourceAccount":"1111111111111"},"ArnLike":{"aws:SourceArn":"arn:aws:logs:ap-northeast-1:111111111111:*"}}}]}'}

Also, near the end, a variable called "new_policy" is created, but since it only contained statement, we modified it to contain the bucket policy after creation.
"put_bucket_policy()" requires a bucket name to be specified as a parameter, so I added it.
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/put_bucket_policy.html

import boto3
import json
s3_client = boto3.client('s3')

bucket_name = 'vpc-flow-log-sudsark'

def lambda_handler(event, context):

    # Or use client to get Bucket policy
    s3_client = boto3.client('s3')
    res = s3_client.get_bucket_policy(Bucket='vpc-flow-log-sudsark')
    policy_json = res['Policy']
    policy = json.loads(policy_json)

    # assign policy using s3 resource 
    user_policy = {
            "Sid": "AutomatedRestrictiveAccess",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::vpc-flow-log-sudsark/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": "333344445555"
                }
            }
        }
    policy['Statement'].append(user_policy)
    new_policy = json.dumps(policy)
    print(new_policy)
    s3_client.put_bucket_policy(Bucket='vpc-flow-log-sudsark', Policy=new_policy)
profile picture
EXPERTE
beantwortet vor 2 Monaten
profile pictureAWS
EXPERTE
überprüft vor 2 Monaten
  • Thanks Riku, this helps . Much appreciated. I just went ahead and looking for further enhancement where I was like checking an option to append only the "aws:SourceAccount": "333344445555" with the existing bucket policy. As an example say I ale4ready have this bucket policy having an account into it already added, then I want to append another account just created with "aws:SourceAccount": "666677778888". While doing so it would help reduce the policy size and also much more better looking. ANy help on this would be greatly appreciated, i am still checking how can i do that no success yet.

  • I think I got it, let me try out .

  • I have tried below code, but its atually returning null in account number, could you please check once and let me know if you found anything of it .

    `import boto3 import json s3_client = boto3.client('s3')

    bucket_name = 'vpc-flow-log-sudsark' NEW_ACCOUNT_ID = '999999999999' def lambda_handler(event, context):

    # Or use client to get Bucket policy
    s3_client = boto3.client('s3')
    res = s3_client.get_bucket_policy(Bucket='vpc-flow-log-sudsark')
    policy_json = res['Policy']
    policy = json.loads(policy_json)
    
    # assign policy using s3 resource 
    
    for statement in policy['Statement']:
        if 'Condition' in statement:
            if 'StringEquals' in statement['Condition']:
                if 'aws:SourceAccount' in statement['Condition']['StringEquals']:
                    if statement['Condition']['StringEquals']['aws:SourceAccount'] is list:
                        statement['Condition']['StringEquals']['aws:SourceAccount'].append(NEW_ACCOUNT_ID)
                    else:
                        statement['Condition']['StringEquals']['aws:SourceAccount'] = list(statement['Condition']['StringEquals']['aws:SourceAccount']).append(NEW_ACCOUNT_ID)
    
    new_policy = json.dumps(policy)
    print(new_policy)
    

    s3_client.put_bucket_policy(Bucket='vpc-flow-log-sudsark', Policy=new_policy)`

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen