Skip to content

feat(storage-s3): presigned URLs for file downloads #12307

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 5, 2025
Merged

Conversation

r1tsuu
Copy link
Member

@r1tsuu r1tsuu commented May 2, 2025

Adds pre-signed URLs support file downloads with the S3 adapter. Can be enabled per-collection:

s3Storage({
  collections: {
    media: { signedDownloads: true }, // or { signedDownloads: { expiresIn: 3600 }} for custom expiresIn (default 7200)
  },
  bucket: process.env.S3_BUCKET,
  config: {
    credentials: {
      accessKeyId: process.env.S3_ACCESS_KEY_ID,
      secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
    },
    endpoint: process.env.S3_ENDPOINT,
    forcePathStyle: process.env.S3_FORCE_PATH_STYLE === 'true',
    region: process.env.S3_REGION,
  },
}),

The main use case is when you care about the Payload access control (so you don't want to use disablePayloadAccessControl: true but you don't want your files to be served through Payload (which can affect performance with large videos for example).
This feature instead generates a signed URL (after verifying the access control) and redirects you directly to the S3 provider.

This is an addition to #11382 which added pre-signed URLs for file uploads.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces pre-signed URL support for file downloads via the S3 adapter with a new per-collection configuration option. Key changes include adding a signedDownloads config option to the S3 storage adapter, incorporating AWS SDK’s GetObjectCommand with getSignedUrl in staticHandler.ts, and updating index.ts to pass the signedDownloads configuration.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/storage-s3/src/staticHandler.ts Adds the signed URL generation block and associated logic for downloads
packages/storage-s3/src/index.ts Updates collection configuration and wiring of signedDownloads value

Copy link
Contributor

@DanRibbens DanRibbens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small feedback, looks like the right approach to me!

We probably also should have an int test.

return async (req, { params: { clientUploadContext, filename } }) => {
let object: AWS.GetObjectOutput | undefined = undefined
try {
const prefix = await getFilePrefix({ clientUploadContext, collection, filename, req })

const key = path.posix.join(prefix, filename)

if (signedDownloads && !clientUploadContext) {
const command = new GetObjectCommand({ Bucket: bucket, Key: key })
const signedUrl = await getSignedUrl(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be cached once we have a strategy for caching or possibly the KV storage.

@r1tsuu r1tsuu requested a review from DanRibbens May 5, 2025 15:14
DanRibbens
DanRibbens previously approved these changes May 5, 2025
@r1tsuu r1tsuu force-pushed the fix/signed-downloads branch from a4c65d5 to bdd09e8 Compare May 5, 2025 19:14
@r1tsuu r1tsuu changed the title feat(storage-s3): pre-signed URLs for file downloads feat(storage-s3): presigned URLs for file downloads May 5, 2025
@r1tsuu r1tsuu merged commit 800c424 into main May 5, 2025
78 checks passed
@r1tsuu r1tsuu deleted the fix/signed-downloads branch May 5, 2025 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants