feat(s3): reconcile browser-upload CORS on the app bucket during sync#92
Merged
Merged
Conversation
The app data bucket (`bucket:`, injected as AWS_BUCKET) is the target for direct browser→S3 presigned-PUT uploads — the pattern replacing Vapor's Vapor.store(). That cross-origin PUT triggers a CORS preflight, so the bucket must carry CORS. YOLO never set it; working apps relied on Vapor having configured it at create. convictrecords is migrating off Vapor and serves its own presigned-upload controller against its adopted bucket, so YOLO now owns the CORS to keep the upload path self-contained. - S3Bucket implements SynchronisesConfiguration: synchroniseConfiguration() reconciles CORS to a permissive managed ruleset (origins *, GET/PUT/HEAD, AllowedHeaders *, MaxAgeSeconds 3600; ExposeHeaders omitted to avoid empty-field phantom drift). create() now applies CORS too. - BPA stays create-only (flipping it under a live public bucket can break it); tags now reconcile on sync, so the step delegates to the standard syncResource() create-or-sync path instead of its bespoke no-op early-return. - Writes go direct via Aws::s3()->putBucketCors (the S3 wrapper holds only read helpers, matching AssetBucket/S3LoadBalancerLogs). - Docs: manifest.md `bucket` section documents the reconciled CORS + tags and the create-only BPA. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey, I made a thing! 🥳
Great! Now please answer the following questions to help out your assigned reviewer:
What problems are you solving?
The app data bucket (
bucket:, injected asAWS_BUCKET) is the target for direct browser→S3 presigned-PUT uploads — the pattern replacing Vapor'sVapor.store()(a hand-rolledSignedStorageUrlControllerissues a presignedputObjectURL; the browser PUTs straight to S3). That cross-origin PUT triggers a CORS preflight, so the bucket must carry a CORS config. YOLO never set it — working apps relied on Vapor having configured it at create. convictrecords is migrating off Vapor and serves its own presigned-upload controller against its adopted bucket, so YOLO now owns the CORS to keep the upload path self-contained and survive a freshly-created bucket.S3Bucketnowimplements SynchronisesConfiguration—synchroniseConfiguration()reconciles CORS to a permissive managed ruleset: origins*, methodsGET/PUT/HEAD,AllowedHeaders *,MaxAgeSeconds 3600.ExposeHeadersis deliberately omitted (AWS drops empty optional fields on read, so an empty value would phantom-drift forever).create()applies CORS too.SyncS3BucketStepdrops its bespoke no-op early-return and delegates to the standardsyncResource()create-or-sync path (reconciles tags + CORS, never touches BPA).Aws::s3()->putBucketCors(...)— the S3 wrapper holds only read helpers, matching howAssetBucket/S3LoadBalancerLogswrite.manifest.mdbucketsection documents the reconciled CORS + tags and the create-only BPA.Is there anything the reviewer needs to know to deploy this?
HEAD/MaxAgeSeconds, or a hand-tuned config) is overwritten with the managed ruleset. The change is surfaced as acorsChange in theyolo syncplan /--checkbefore apply.*origins just let the preflight pass (and keep the cutover canaryfargate.<app>+ bare-ALB origin working).documentsEqualdrift logic but not S3's real CORS echo. Worth eyeballing the firstconvictrecordssync:app production --checkwhen that cutover lands, to confirm the managed ruleset round-trips without perpetual drift.*.testCORS are set separately. No POST / multipart methods (single presigned PUT only).pintclean · 616 Pest pass (1490 assertions) ·phpstanno errors.🤖 Generated with Claude Code