Skip to content

R2 event receiver (Phase 5b)

workers/r2-event-receiver is the Cloudflare Worker that bridges customer R2 event notifications into our AWS SQS s3_ingest queue. It replaces the role EventBridge plays for AWS customers β€” R2 can’t target an external HTTPS endpoint directly, so customers deploy a tiny forwarder Worker (template fetched from the dashboard) that POSTs to this receiver.

One-time setup

  1. Deploy the CDK Integrations stack (creates the IAM user):

    Terminal window
    cd infra/cdk
    npx cdk deploy AccessiblePdfIntegrationsStack-production

    Note the R2EventReceiverUserArn output.

  2. Create an access key for that IAM user:

    Terminal window
    aws iam create-access-key --user-name accessible-pdf-production-r2-event-receiver

    Save the AccessKeyId + SecretAccessKey immediately β€” AWS will not show the secret again.

  3. Configure CF Worker bindings. Sensitive values use wrangler secret put; non-sensitive ones go in [vars] in wrangler.toml:

    Vars (already set or set in wrangler.toml):

    • AWS_REGION (e.g. us-east-1)
    • SQS_QUEUE_URL (from QueueStack output)
    • SUPABASE_URL (e.g. https://xxx.supabase.co)

    Secrets:

    Terminal window
    cd workers/r2-event-receiver
    wrangler secret put AWS_ACCESS_KEY_ID --env production # from step 2
    wrangler secret put AWS_SECRET_ACCESS_KEY --env production # from step 2
    wrangler secret put SUPABASE_SERVICE_KEY --env production # service-role JWT
  4. Deploy the Worker:

    Terminal window
    npm run deploy
  5. Wire the custom domain (one-time, in CF dashboard): r2-event.theaccessible.org β†’ accessible-r2-event-receiver.

Operational notes

  • The Worker rate-limits each integrationId to 100 requests / 10 s. Customers exceeding that get 429s; their R2 Queue redelivers, so events are not lost (assuming the Queue’s retention window covers the burst).
  • The Worker validates event_source_secret against Supabase before signing+sending to SQS, so junk POSTs can’t drive up SQS bills.
  • Rotating an integration’s secret (POST .../event-source-secret/rotate) invalidates any customer Worker template generated before the rotation. The dashboard surfaces a note about this. Old events fail fast at the receiver (401) and at the consumer (Phase 5a check).

Key rotation

  • Rotate the IAM user’s access key annually:
    Terminal window
    aws iam create-access-key --user-name accessible-pdf-production-r2-event-receiver
    # Update CF Worker secrets with the new pair
    wrangler secret put AWS_ACCESS_KEY_ID --env production
    wrangler secret put AWS_SECRET_ACCESS_KEY --env production
    # Once traffic flows green on the new key, retire the old one
    aws iam delete-access-key --user-name accessible-pdf-production-r2-event-receiver \
    --access-key-id <OLD_KEY_ID>

Troubleshooting

SymptomLikely cause
All events 401 at receiverCustomer Worker template stale (secret rotated). Re-copy from dashboard.
All events 502 at receiverAWS_* secrets wrong, or IAM user lacks sqs:SendMessage.
Events accepted (202) but nothing happensCheck S3IngestLambda CloudWatch logs β€” likely event_unauthorized due to secret drift between receiver and consumer.
Customer sees 429sTheir R2 traffic exceeds 100 events / 10 s. Bump the rate-limit binding in wrangler.toml if legitimate.