Python SDK analytics export to S3 failing with 403 Forbidden on boto3 put_object

We are implementing a daily automation job to extract conversation analytics from Genesys Cloud and push the raw JSON payload directly to an S3 bucket. The goal is to bypass the standard report scheduler and have full control over the file structure. The script runs on an EC2 instance in the EU-West-1 region, which matches our Genesys Cloud instance location.

The authentication flow uses the platform client library to fetch a valid JWT, which works perfectly for the initial GET request to /api/v2/analytics/conversations/details/query. We are getting a 200 OK with the expected data. The issue arises when we attempt to write this data to S3 using boto3.

Here is the relevant section of the code:

import boto3
from platformclientv2 import PlatformClient

# ... auth setup omitted for brevity ...

analytics_client = platform_client.analytics_api
body = QueryRequest()
body.date_from = "2023-10-01T00:00:00.000Z"
body.date_to = "2023-10-02T00:00:00.000Z"

response = analytics_client.post_analytics_conversations_details_query(body)

s3 = boto3.client('s3', 
 aws_access_key_id=os.environ['AWS_ACCESS_KEY_ID'],
 aws_secret_access_key=os.environ['AWS_SECRET_ACCESS_KEY'],
 region_name='eu-west-1'
)

try:
 s3.put_object(
 Bucket='genesys-backups-daily',
 Key='analytics/voice/2023-10-01.json',
 Body=json.dumps(response.body)
 )
except Exception as e:
 print(f"S3 Error: {e}")

The error message returned is An error occurred (403) Forbidden. The IAM role attached to the EC2 instance has s3:PutObject permissions on that specific bucket. I have verified the credentials by running aws s3 ls from the terminal on the same instance, which works without issue. It seems like the Python boto3 client is not picking up the credentials correctly or there is a session conflict with the Genesys SDK. The JSON payload is valid and small, so it’s not a size limit issue. Has anyone seen this specific conflict between the Genesys Platform SDK and boto3 in the same execution context?