Posted in Active Storage, AWS S3 and Cloudfront
Here's what worked for me:
I chose to abandon ActiveStorage completely (don't worry, this makes things easier). Once the upload button is clicked on the client, a GET /presigned_url is sent to the server and I use the aws gem to get an s3 presigned URL and send it back in the response. The client picks up this URL and uploads directly to it using XHR. Upon successful upload, S3 responds with the permanent location which the client finally POSTS back to rails to create the resource with a picture_url attribute. I also have a cdn_url method in my model which uses some regex to extract the filename and append it to my CloudFront domain.
This approach delegates the hard work to the client which has some speed benefits (only uploads to one location and doesn't keep the backend blocked while doing uploads). Let me know if you'd like to see the repo where I did this.