Storage providers

CORS Considerations

Configure bucket CORS for browser uploads, HLS playback, and thumbnails.

CORS controls whether browser code can access responses from another origin. Browser uploads and media playback need separate permissions on your storage bucket.

Browser uploads to customer storage

When you upload a local file through the Chunkify dashboard or an uploader on your website, the browser sends the file directly to the selected storage. This applies to all customer-connected storage, whether it is the project's default or an upload override.

Configure CORS on the bucket at your storage provider. Connecting the storage to Chunkify does not configure CORS automatically. Chunkify manages this configuration for Chunkify storage.

The storage connection needs PutObject, HeadObject, and GetObject permissions. CORS is a separate setting: valid storage credentials alone do not allow a browser upload.

Allow the origin of the page where the uploader runs, the PUT method, and the request headers it sends. The Chunkify uploader sends Content-Type.

Choose the allowed origins based on where users upload files:

  • For the Chunkify dashboard, allow https://chunkify.dev.
  • For an uploader embedded on your website, allow your website's origin, such as https://app.example.com.
  • For local development, allow the exact local origin, such as http://localhost:3000.

An origin includes the protocol, hostname, and port if present, with no path or trailing slash. If users upload through both the dashboard and your website, allow both origins.

For AWS S3 and providers that support the S3 bucket CORS API, save this configuration as cors.json. This example allows uploads from both the Chunkify dashboard and your website. Replace https://app.example.com with your website's origin and keep only the origins you use:

{
  "CORSRules": [{
    "AllowedOrigins": ["https://chunkify.dev", "https://app.example.com"],
    "AllowedMethods": ["PUT"],
    "AllowedHeaders": ["Content-Type"],
    "MaxAgeSeconds": 3600
  }]
}

MaxAgeSeconds is optional. The value 3600 lets the browser cache a successful CORS preflight check for up to one hour, reducing repeated checks for matching requests. It does not limit upload duration or change the upload URL's expiration.

Apply it using the AWS CLI with credentials for your storage provider that can change bucket CORS:

aws --endpoint-url "$ENDPOINT_URL" --region "$STORAGE_REGION" s3api put-bucket-cors \
  --bucket "$BUCKET_NAME" \
  --cors-configuration file://cors.json

Set ENDPOINT_URL, STORAGE_REGION, and BUCKET_NAME to your storage's values. For AWS S3, omit --endpoint-url. You can also use your provider's CORS settings or API; its configuration format may differ.

This operation replaces the bucket's CORS configuration. Include existing rules, such as those used for media playback, in the configuration you apply. See the AWS S3 and Backblaze B2 API documentation.

The browser sends an OPTIONS preflight before the upload. The storage provider checks it against the rule for PUT; do not add OPTIONS to S3's AllowedMethods.

Test from each website that will host the uploader. A successful curl upload or storage connection check does not verify browser CORS. If the browser blocks the upload, check its Network panel for the storage preflight and confirm the origin, method, and headers match your rule.

The upload completion endpoint has its own CORS handling. It does not change bucket CORS. Creating a Source from an existing storage object or a video URL does not transfer a file from the browser and does not need this upload rule.

Media playback

When using HLS or thumbnails in web players, configure cross-origin access if the media is served from a different origin than your web application.

Solutions:

  • Configure your storage origin or CDN to allow cross-origin requests
  • Use a CORS proxy service
  • Host your media files on the same domain as your website

When you configure a storage CDN base URL in Chunkify, CORS remains your responsibility. Apply compatible rules at both the CDN edge and storage origin.

Confirm the CDN forwards Range request headers. It must also preserve Content-Range, Accept-Ranges, and media Content-Type response headers.

S3 Bucket CORS Configuration

CLI Configuration

Here is an example of how to configure your S3 bucket to allow cross-origin requests.

aws --endpoint-url=$ENDPOINT_URL s3api put-bucket-cors \
  --bucket your-production-bucket \
  --cors-configuration '{
    "CORSRules": [{
      "AllowedHeaders": ["*"],
      "AllowedMethods": ["GET"],
      "AllowedOrigins": [
        "https://yourdomain.com",
        "https://www.yourdomain.com",
        "https://app.yourdomain.com"
      ],
      "ExposeHeaders": [],
      "MaxAgeSeconds": 3600
    }]
  }'

Console Configuration

Here is an example of how to configure your S3 bucket to allow cross-origin requests using the console.

  • Go to AWS S3 Console
  • Select your bucket
  • Click on the "Permissions" tab
  • Scroll down to "Cross-origin resource sharing (CORS)"
[
    {
        "AllowedHeaders": ["*"],
        "AllowedMethods": ["GET"],
        "AllowedOrigins": [
            "https://yourdomain.com",
            "https://www.yourdomain.com",
            "https://app.yourdomain.com"
        ],
        "ExposeHeaders": [],
        "MaxAgeSeconds": 3600
    }
]

Some media players also need HEAD in the allowed methods. S3 handles OPTIONS preflight requests from the configured rules.