Skip to main content
General
Storage

Overview

Learn how the shipped S3-compatible image storage flow works.

Open MarkdownFull AI corpusFeedback

The Pro Next.js Prisma kit ships a focused image storage flow for avatars and organization logos. Both Pro kits use the same storage implementation.

Upload flow

  1. A signed-in user selects and crops an image in the browser.
  2. The client calls storage.signedUploadUrl with an object key and the configured images bucket.
  3. The protected tRPC procedure checks only that the bucket equals storageConfig.bucketNames.images.
  4. getSignedUploadUrl validates the key syntax and returns a PutObject URL that expires after 60 seconds.
  5. The browser uploads directly to the storage provider.
  6. Better Auth stores the object key in the user image field or organization logo field.

The server does not create an ownership record for the object. It also does not derive the key from the authenticated user, enforce a size limit or inspect the uploaded bytes.

Read flow

  1. useStorage(image) returns /storage/{imagesBucket}/{image} for a local image key.
  2. The public route reads the bucket and image key from the URL.
  3. If the bucket matches the configured images bucket, it returns a redirect to a signed GetObject URL.
  4. The signed URL and redirect cache both use a one-hour lifetime.

The route does not read the current session. It does not query the database or verify ownership. This is suitable for product images that are intended to be displayed wherever their key is known, not for confidential files.

Included functions

lib/storage/s3.ts
getSignedUploadUrl(path, bucket); // PutObject URL, 60 seconds
getSignedUrl(path, bucket, expiresIn); // GetObject URL

Both functions validate that a path:

  • Is not absolute
  • Contains no .., null byte or hidden path segment
  • Uses only letters, numbers, hyphens, underscores, slashes and dots

Path validation prevents malformed object keys. It is not a user or organization authorization check.

Current scope

CapabilityShipped behavior
Avatar and logo uploadIncluded
Direct browser uploadIncluded
Authenticated upload signingIncluded
Public image redirectIncluded
Private file authorizationNot included
File ownership metadataNot included
Listing and deletion APIsNot included
Storage quota enforcementNot included
Nested-key download routingNot included

Use the included integration as a starting point for public display images. Build a separate authorized download flow for private files.