Storage
Storage
The storage layer is compatible with S3-style providers such as AWS S3, Cloudflare R2, and MinIO.
Main files
| Path | Purpose |
|---|
src/features/storage/providers/s3.ts | S3-compatible provider |
src/features/storage/actions.ts | Storage Server Actions |
src/features/storage/utils.ts | Utility helpers |
src/features/storage/types.ts | Storage types |
src/app/api/upload/presigned/route.ts | Presigned upload endpoint |
src/app/image-proxy/[...path]/route.ts | Image proxy route |
src/test/storage/security.test.ts | Storage security tests |
Environment variables
| Variable | Purpose |
|---|
STORAGE_ENDPOINT | Provider endpoint, for example R2 endpoint |
STORAGE_REGION | S3 region or provider-compatible value |
STORAGE_BUCKET | Bucket name |
STORAGE_ACCESS_KEY_ID | Access key |
STORAGE_SECRET_ACCESS_KEY | Secret key |
Upload model
- Client requests a presigned upload URL.
- Server validates the request and returns upload metadata.
- Client uploads directly to the storage provider.
- App stores or uses the returned object key.
- 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