Skip to main content
Solutions/Tech Stack/Saas
Tech Stack · Web Application

S3 is the right choice for large-scale file storage. The access control patterns are where it goes wrong.

S3 presigned URLs, bucket policies, CORS configuration, and the lifecycle rules that manage storage costs — implemented correctly for production applications that need file uploads, downloads, and private asset serving.

150+
Projects shipped
99%
Client retention
~12wk
Average delivery
The problem
Application that needs file storage and is either using S3 incorrectly (public buckets with sensitive files) or hasn't configured presigned URLs correctly

S3 file storage has a well-documented security failure mode: public buckets. In 2017–2019, hundreds of companies exposed sensitive user data via publicly readable S3 buckets. The pattern: developers configuring bucket access incorrectly (or turning off "Block Public Access" for convenience) and inadvertently making private files publicly accessible to anyone with the URL.

The correct S3 pattern for user files:

Upload via presigned URL. The browser never sends files to your application server. Instead, the backend generates a presigned URL (a temporary, scoped permission to upload to a specific S3 object) and returns it to the frontend. The browser uploads directly to S3 using the presigned URL. The S3 bucket never needs to be public.

Download via presigned URL. The same pattern for downloads. The backend generates a presigned GET URL with a short expiry (15 minutes). The user's browser fetches the file directly from S3. The URL expires; the file remains private.

Private bucket policy. The S3 bucket is configured with Block Public Access enabled. No object is publicly accessible. Only presigned URLs or CloudFront signed URLs provide access.

CORS configuration. S3 needs CORS rules configured for the specific origins allowed to upload from the browser (your application domain).

What we build

S3 file storage with presigned upload URLs, private bucket access, CORS configuration, and the download flow that keeps files secure

Presigned upload URLs

Backend Route Handler that generates presigned S3 PUT URLs. Returns the URL and the final object key to the frontend. Frontend uploads directly to S3.

Presigned download URLs

Backend Route Handler that verifies user authorization, then generates presigned S3 GET URLs. URLs expire after a configurable period.

Private bucket configuration

S3 bucket with Block Public Access. Bucket policy that allows only the application's IAM role. CORS configuration for browser uploads.

File metadata tracking

File metadata (user, filename, content type, size, S3 key) stored in Postgres. Files retrieved by key, not by S3 URL.

Lifecycle policies

S3 lifecycle rules to transition old files to cheaper storage tiers (S3 Intelligent-Tiering or Glacier) and delete temporary files after a defined retention period.

Engagement

One honest number to start.

Fixed-scope, fixed-price. The number below is the starting point — final scope is built from your brief.

Tier · Web ApplicationFixed scope
From$25,000

S3 file storage with presigned upload URLs, private bucket access, CORS configuration, and the download flow that keeps files secure

99% client retention across 40+ projects
Process

Three steps, every time.

The same repeatable engagement on every project. No surprises, no mystery, no billable ambiguity.

01Week 0

Brief & discovery.

We send you questions, then get on a call. Output: a written scope with every step, feature, and integration listed.

02Weeks 1–N

Build & ship.

Fixed schedule, weekly reviews. No scope creep unless you change the scope — and if you do, we reprice it transparently.

03Post-launch

Warranty & retainer.

30-day warranty on every launch. Most clients stay on a monthly retainer for ongoing features and maintenance.

Why fixed-price

Why Fixed-Price Matters Here

S3 integration scope is defined by the file types, access patterns, and retention requirements. Fixed price.

FAQ

Questions, answered.

UploadThing is a developer-friendly abstraction over S3 that simplifies the presigned URL workflow and Next.js integration. For new applications, UploadThing is faster to implement. For applications that need specific S3 features (lifecycle rules, cross-region replication, specific IAM policies), direct S3 is more appropriate.

S3 storage is $0.023/GB/month for standard storage. Data transfer OUT costs $0.09/GB. For applications with large download volumes, CloudFront CDN in front of S3 reduces egress costs and improves download speed.

Part of the application build. Full application from $25k. Fixed-price.

Next step

Tell Ryel about your project.

Describe what you’re building and what outcome you need. You’ll have a written, fixed-price scope within the week.