Signed S3 setup

Hi, I’m struggling to setup Workers for private S3 resources

I have CNAME for assets to and available script route for assets.domain/*.

Worker script

var v4 = require(‘aws-signature-v4’)

async function handleRequest(request) {
const parsedUrl = new URL(request.url)
let path = parsedUrl.pathname

if (path === “/”) {
return new Response(’’, {
status: 404

let url = v4.createPresignedS3URL(path.substr(1), {
bucket: ‘bucket’,
key: API_KEY,
secret: SECRET_KEY

return fetch(url)

addEventListener(‘fetch’, event => {

Basically in worker editor all seems great, but if I try to access asset url (https://assets.domain/some_picture.png) outside of editor I get 403 and worker dashboard doesn’t register invocation.

I can’t get what I’m doing wrong here.


Have you made sure that the path was enabled in the routes section and the subdomain is :orange: in the DNS page?

Yeap, path is enabled and subdomain in DNS (DNS errors are easier to track since response end up with according error).

I’ve tried directly mention prefix https://assets.domain/* in routes, still no results.

Let me express a bit more my reasoning:

  1. seeing a 403 means that the origin doesn’t allow that action, but if it works for the same URL in the preview that shouldn’t be the issue. The 403 is never generated by Cloudflare, but by the origin.
  2. not having the invocation seen on the dashboard (note that there is a delay in that) suggest that something is wrong with the configuration of the routes (if the code were wrong the error would be different).

I’m kinda at a loss here. I am gonna think about that, but maybe in the meantime let’s see if @cloonan or @KentonVarda have ideas.

Thanks for help.
I’ve figured out what was going on. The problem wasn’t in routing or in script.
I have 3 levels domain (, but Cloudflare provide free ssl certificate only for first and second level. Browser just failed to establish https connection ans cancel requests. That’s why I haven’t seen worker requests in dashboard (or I believe so).

Basically removing one level (e.g. assets.server -> assets-server or something) fixed the issue.

1 Like

If you wanted to keep the third level you could always buy a dedicated certificate for 10$/month.

Glad it works now! It should give a 403 though. Let’s not try to solve something while it works :joy::sweat_smile: