Storage

Storage

The storage layer is compatible with S3-style providers such as AWS S3, Cloudflare R2, and MinIO.

Main files

PathPurpose
src/features/storage/providers/s3.tsS3-compatible provider
src/features/storage/actions.tsStorage Server Actions
src/features/storage/utils.tsUtility helpers
src/features/storage/types.tsStorage types
src/app/api/upload/presigned/route.tsPresigned upload endpoint
src/app/image-proxy/[...path]/route.tsImage proxy route
src/test/storage/security.test.tsStorage security tests

Environment variables

VariablePurpose
STORAGE_ENDPOINTProvider endpoint, for example R2 endpoint
STORAGE_REGIONS3 region or provider-compatible value
STORAGE_BUCKETBucket name
STORAGE_ACCESS_KEY_IDAccess key
STORAGE_SECRET_ACCESS_KEYSecret key

Upload model

  1. Client requests a presigned upload URL.
  2. Server validates the request and returns upload metadata.
  3. Client uploads directly to the storage provider.
  4. App stores or uses the returned object key.
  5. Public display can go through the image proxy when needed.

Security checklist

  • Validate file type and size before creating presigned URLs.
  • Keep object keys scoped and hard to guess.
  • Do not expose secret keys to the browser.
  • Prefer private buckets plus signed reads or proxy routes.
  • Run storage security tests after changing upload rules.
pnpm test:run src/test/storage

On this page