Skip to content

fix(csp): allow the private S3 bucket origin in connect-src (uploads died on CSP-serving domains) - #322

Merged
lopugit merged 1 commit into
developfrom
claude/csp-allow-s3-uploads
Aug 19, 2026
Merged

fix(csp): allow the private S3 bucket origin in connect-src (uploads died on CSP-serving domains)#322
lopugit merged 1 commit into
developfrom
claude/csp-allow-s3-uploads

Conversation

@lopugit

@lopugit lopugit commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Why uploads die on pr-*.previews.dev.thingtime.com (and will die on prod when the CSP ships)

Lopu hit 'The file could not reach storage. Check your connection and retry.' on every upload at pr-312.previews.dev.thingtime.com. Diagnosis:

  • The composer's upload path is a browser-direct S3 multipart PUT (signed part URLs).
  • That domain serves the application CSP whose connect-src is only 'self' https://cdn.jsdelivr.net — the browser kills the PUT to https://<bucket>.s3.<region>.amazonaws.com before it leaves, which surfaces as exactly that upload-phase error.
  • Bucket CORS is NOT the problem: preflight OPTIONS against the develop bucket returns 200 + Access-Control-Allow-Origin for the preview origins (verified for both pr-312.previews.dev.thingtime.com and the *.vercel.app alias).
  • *.vercel.app previews carry no CSP header at all, which is why uploads work there today.

Fix

csp.mjs (single source of truth consumed by patch-vercel-output / verify-vercel-output / vite dev headers) now adds the private bucket origin to connect-src: exact https://$BUCKET.s3.$REGION.amazonaws.com derived from THINGTIME_PRIVATE_S3_BUCKET/_REGION at build time, falling back to the regional wildcard https://*.s3.ap-southeast-2.amazonaws.com when the env is absent (local dev, env-less builds).

Verified: both env modes produce the expected policy; lint clean; changelog entry added under [Unreleased].

Note: separately, fresh accounts on that environment 403 at upload prepare — that's the #309 upload-permission gate working as designed, not this bug.

🤖 Generated with Claude Code

The app CSP never allowed the direct-to-S3 multipart PUT the composer
performs, so every attachment upload died in the browser with 'The
file could not reach storage' on any surface serving the header
(pr-*.previews.dev.thingtime.com, dev, staging - and production once
the policy ships there). Bucket CORS was already correct; only the
page policy blocked the connection. connect-src now carries the exact
bucket origin derived from THINGTIME_PRIVATE_S3_BUCKET/_REGION at
build time, with a regional wildcard fallback when the env is absent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thingtime Ready Ready Preview Aug 19, 2026 4:43am
thingtime (develop) Ready Ready Preview Aug 19, 2026 4:43am

Request Review

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🧹 Develop S3 preview removed

The PR-specific alias and every workflow-created develop deployment were removed when this PR closed.

The ordinary generated Vercel Preview remains available on the shared development runtime.

@github-actions
github-actions Bot temporarily deployed to develop-pr-322 August 19, 2026 04:42 Destroyed
@lopugit
lopugit merged commit c73565d into develop Aug 19, 2026
35 checks passed
@lopugit

lopugit commented Aug 19, 2026

Copy link
Copy Markdown
Owner Author

🤖 Promotion conflict resolution was queued automatically for promote/pr-322-csp-allow-s3-uploads--to-main at exact base main (440c30d738a0da37cd21d3f65aa057489f58f41d).

Conflicted source paths: remix/CHANGELOG.md, remix/scripts/csp.mjs.

The trusted worker will reconstruct, verify, publish, and attest the review branch; no manual branch update is needed.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

✅ The trusted promotion worker opened #324 for promote/pr-322-csp-allow-s3-uploads--to-main.

Review the exact resolved paths and immutable snapshot in the promotion PR comment. Workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Verified automatic promotion resolution for promote/pr-322-csp-allow-s3-uploads--to-main at af38cca7aa168e5a890d977bc29bf926019444df.

This marker is inert until the live remote branch equals the attested head. Workflow run.

github-actions Bot added a commit that referenced this pull request Aug 19, 2026
Thingtime-Promotion-Source-PR: 322

Thingtime-Promotion-Base-Ref: main

Thingtime-Promotion-Base-SHA: 440c30d

Thingtime-Promotion-Branch: promote/pr-322-csp-allow-s3-uploads--to-main

Thingtime-Promotion-Source-Tip-SHA: c73565d

Thingtime-Promotion-Source-Start-SHA: dfca890

Thingtime-Promotion-Source-End-SHA: c73565d

Thingtime-Promotion-Source-Lineage: verified

Thingtime-Promotion-Plan-Hash: 8cc9adfd69e3162cf56abae635a546219281ef65db7fcd93f8caa0d340682f64

Thingtime-Promotion-Patch-ID: 6794355390a1e7988f5dbd1024e5104817f044ac

Resolved by the promotion worker: https://github.com/lopugit/thingtime/actions/runs/32222553788
lopugit added a commit that referenced this pull request Aug 20, 2026
…ads--to-main

[Promote][csp #1] fix(csp): allow the private S3 bucket origin in connect-src (uploads died on CSP-serving domains) (#322)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant