You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With S3_ENDPOINT set, sign x-amz-meta-* upload metadata as headers (unhoistableHeaders) and return them for the uploader to send, instead of letting the presigner hoist them into the query string. S3-compatible stores such as OVHcloud, SeaweedFS, and RustFS ignore query-string metadata, so the object landed without uploadId and completion failed with "missing required provider metadata". Signed-header metadata is what the other official AWS SDKs do and works on every store checked
AWS (no S3_ENDPOINT) keeps the query-string form unchanged, so existing bucket CORS rules can't regress
Add the S3_ENDPOINT origin (port kept) to connect-src in both build-time and runtime CSP, plus *.host for virtual-hosted addressing (skipped for S3_FORCE_PATH_STYLE and IP hosts, which the SDK always addresses path-style). Previously the browser blocked every direct upload to a custom endpoint
Docs: S3-compatible buckets need CORS AllowedHeaders: ["*"] (or Content-Type, If-None-Match, and the x-amz-meta-* headers)
presigned-upload.test.ts runs the real SigV4 presigner (local, no network): metadata is signed as headers for a custom endpoint, stays in the query for AWS, and every signed header the uploader controls is supplied with nothing both hoisted and sent
csp.test.ts: virtual-hosted, path-style + port, IP host, scheme-less endpoint, and build-time policy
New-behavior tests fail with the fix reverted; AWS-unchanged guards pass before and after
bun run lint, type-check, check:audits (52/52), docs-manifest:check
Checklist
Code follows project style guidelines
Self-reviewed my changes
Tests added/updated and passing (new tests pass the test-audit authoring gate)
[High risk] Changes how upload metadata is signed for S3-compatible storage.
The PR appears safe to merge; the previously reported environment-dependent test has been fixed.
Summary
The PR sends signed upload metadata as headers for custom S3 endpoints, permits those endpoints in the browser CSP, and updates tests and storage documentation. Since the previous review, it also pins the CSP test’s path-style setting as unset.
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
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.
Summary
S3_ENDPOINTset, signx-amz-meta-*upload metadata as headers (unhoistableHeaders) and return them for the uploader to send, instead of letting the presigner hoist them into the query string. S3-compatible stores such as OVHcloud, SeaweedFS, and RustFS ignore query-string metadata, so the object landed withoutuploadIdand completion failed with "missing required provider metadata". Signed-header metadata is what the other official AWS SDKs do and works on every store checkedS3_ENDPOINT) keeps the query-string form unchanged, so existing bucket CORS rules can't regressS3_ENDPOINTorigin (port kept) toconnect-srcin both build-time and runtime CSP, plus*.hostfor virtual-hosted addressing (skipped forS3_FORCE_PATH_STYLEand IP hosts, which the SDK always addresses path-style). Previously the browser blocked every direct upload to a custom endpointAllowedHeaders: ["*"](orContent-Type,If-None-Match, and thex-amz-meta-*headers)Fixes #8378
Type of Change
Testing
presigned-upload.test.tsruns the real SigV4 presigner (local, no network): metadata is signed as headers for a custom endpoint, stays in the query for AWS, and every signed header the uploader controls is supplied with nothing both hoisted and sentcsp.test.ts: virtual-hosted, path-style + port, IP host, scheme-less endpoint, and build-time policybun run lint,type-check,check:audits(52/52),docs-manifest:checkChecklist
test-auditauthoring gate)🤖 Generated with Claude Code