I found the solution to my own question! Please read this if you're having issues. I also posted this on social media. Here's the fix. It was a runtime issue.
Goal: I needed to load a protected video on page load using a CloudFront-signed URL, with viewer restriction enabled and a trusted key group. The goal? One-hour secure access to a video — simple in theory.
Error: No matter how I signed the URL manually, CloudFront kept denying access.
The real fix?
Installing the AWS SDK for PHP directly inside my WordPress project root (/var/www/html) using Composer — not globally
Switching to a canned policy, which was the correct match for my use case (short-lived, secure URLs — no IP or wildcard conditions needed)
Using the SDK’s UrlSigner class to cleanly and securely generate the signed URL — instead of manually building it with openssl_sign()
This wasn’t just a config issue — it was a runtime-level problem with how the signing was handled inside WordPress/PHP.
Now, the video loads instantly, signed and secure — exactly as expected.
Sometimes it’s not your CloudFront config that’s broken… it’s how you’re signing it.