Skip to content

S3-Compatible Storage Integration for Media Library #586

@alizaenazet

Description

@alizaenazet

Summary

Add support for Amazon S3 and S3-compatible storage providers (DigitalOcean Spaces, Cloudflare R2, Wasabi, MinIO, etc.) as a media library option in Sveltia CMS.

Motivation

1. Cost-Effective Storage

Many S3-compatible providers offer significantly cheaper storage compared to Cloudinary/Uploadcare:

  • DigitalOcean Spaces: $5/month for 250GB + 1TB transfer
  • Cloudflare R2: $0.015/GB, zero egress fees
  • Wasabi: $6.99/TB/month, no egress fees
  • Local providers: Many regional cloud providers offer S3-compatible storage (often powered by MinIO/Wasabi) at competitive prices

2. Leverage Existing Infrastructure

Many users already have S3 buckets for their sites (e. g., hosting on S3 + CloudFront). This integration allows them to:

  • Use the same bucket for CMS media
  • Avoid vendor lock-in with proprietary services
  • Integrate with existing CDN/backup workflows

3. Compatibility with Built-in Image Optimization

Sveltia CMS already has excellent WebP compression and image optimization features. With S3 integration, users can:

  • Upload images into automatically convert to WebP and store in S3
  • Apply transformations (resize, compress) before upload
  • Reduce storage costs with optimized images
  • Improve site performance with smaller files

Currently, this optimization only works with the default (Git-based) media library. S3 integration would unlock this for cloud storage users.

4. Consistency with Existing Pattern

Sveltia CMS already supports multiple media libraries (Cloudinary, Uploadcare, stock photos). S3 is a natural addition that:

  • Follows the same plugin architecture
  • Works with the existing media_libraries configuration
  • Provides users with more choice

Outline of the Idea

Stage 1: Direct Access (Initial Implementation)

Users enter AWS credentials in the CMS UI (stored in browser memory during session only).

Configuration Example:

media_libraries:
  s3:
    config:
      bucket: my-bucket
      region: us-east-1
      # Optional: for S3-compatible services
      endpoint: https://nyc3.digitaloceanspaces.com
      force_path_style: true  # Required for MinIO, DigitalOcean Spaces

User Experience:

  1. User opens Asset Library
  2. CMS prompts: "Enter AWS Access Key ID and Secret Access Key"
  3. User enters credentials (similar to Cloudinary's API Secret prompt)
  4. CMS generates AWS Signature V4 and makes direct API calls to S3
  5. Credentials are never stored in config files, only in memory

Security:

  • No credentials in config files (same approach as Cloudinary)
  • Credentials discarded after session
  • All requests signed with AWS Signature V4
  • Requires proper S3 bucket CORS configuration

Pros:

  • Simple implementation (single file: s3.js)
  • No backend required
  • Works immediately for all users
  • Easy to test/debug

Cons:

  • Credentials in browser memory (XSS risk, but same as Cloudinary approach)
  • Developer need to configure S3 CORS policy as part of setup.

Stage 2: Presigned URLs via Backend (Future Enhancement)

For users who want maximum security, add support for backend-generated presigned URLs.

Configuration Example:

media_libraries:
  s3:
    config:
      bucket: my-bucket
      region: us-east-1
      use_presigned_urls: true
      endpoint: /.netlify/functions/s3-handler  # User's backend

User Experience:

  1. User deploys a simple serverless function (Netlify/Vercel/etc.)
  2. Function holds AWS credentials in environment variables
  3. CMS requests presigned URLs from the function
  4. CMS uploads directly to S3 using presigned URLs

Security:

  • AWS credentials never exposed to browser
  • Backend controls access/permissions
  • Works behind corporate firewalls
    Pros:
  • Most secure option
  • Fine-grained access control
  • Credentials in environment variables
    Cons:
  • Requires backend deployment
  • More complex setup

S3-Compatible Provider Support

The implementation should support these providers (all use AWS Signature V4):

Provider Compatibility Notes
AWS S3 ✅ 100% Reference implementation
MinIO ✅ 100% Self-hosted, requires force_path_style: true
DigitalOcean Spaces ✅ 98% Requires force_path_style: true
Cloudflare R2 ✅ 99% May need public_url_template for CDN URLs
Wasabi ✅ 95% Works with custom endpoint
Backblaze B2 (NO) ⚠️ 80% Different auth model (future consideration)

i just see the opensource alternatice of cloudinary at openinary, which is also Compatible is S3, so in the future will be possible to make self hosted cloudinary with sveltia in small cheap vps.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions