For example, my css code has this image file:
background: url('/static/studyspot5/images/shapes/footer_sass.png');
And it does not render on my AWS site I have the following relevant code in my settings.py:
if USE_S3:
STATICFILES_LOCATION = 'static'
MEDIAFILES_LOCATION = 'media'
MEDIA_URL = f'https://{CLOUDFRONT_DOMAIN}/{MEDIAFILES_LOCATION}/'
MEDIA_ROOT = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/{MEDIAFILES_LOCATION}/'
STATIC_URL = 'https://%s/%s/' % (CLOUDFRONT_DOMAIN,STATICFILES_LOCATION)
STATIC_ROOT = 'https://%s/%s/static/' % (AWS_S3_CUSTOM_DOMAIN,STATICFILES_LOCATION)
STORAGES = {
"default": {"BACKEND": 'custom_storages.MediaStorage'},
"staticfiles": {"BACKEND": 'custom_storages.StaticStorage'},
"OPTIONS": {
"bucket_name": AWS_STORAGE_BUCKET_NAME,
"region_name": AWS_S3_REGION_NAME,
# "verify": AWS_S3_VERIFY,
"signature_version": AWS_S3_SIGNATURE_VERSION,
"cloudfront_key_id": AWS_CLOUDFRONT_KEY_ID,
"cloudfront_key": AWS_CLOUDFRONT_KEY,
"custom_domain": CLOUDFRONT_DOMAIN,
},
}
The CSS file (and all other static content) is served as a signed URL just fine, e.g. using the following code:
<link rel="stylesheet" href="{% static 'studyspot5/css/style.css' %}">
But for those urls inside of CSS files, it will only pass the url of the file, without signing it (no parameters). Here is the resulting request headers. Note the referer URL is signed, but the darn background image from the CSS is not!

I have ended up going with a second, public, bucket, in spite of that defeating the whole purpose of using cloudfront. At least most of my content will be delivered via signed urls, it's better than nothing.
I got the idea from a similar question: Static website private content Amazon S3 and Cloudfront - css, js and images not showing.