How to specify S3 object key when using STS

I’m looking to integrate Uppy into a project for direct-to-S3 file uploads.It appears the S3 plugin was recently completely rewritten with new backend hooks, which confuses things a bit, and I haven’t been able to answer my question based on looking at the new demo code.

I would like to use the STS-based approach but limit the federation token that is fetched by the backend to a specific S3 object key. To do this, I need to:

  1. Pass the name of the file upload from Uppy to the backend so it can construct the appropriate S3 object key based on some backend logic.
  2. Pass the full S3 object key back to Uppy and have it use that key for the upload.

I can’t see where that information can be communicated in the new getCredentials hook, or where else it can be passed along. Any help is greatly appreciated, thanks.

Hi there, the demo code you found in example is ahead of what’s released, latest published version is @uppy/aws-s3@5.1.0, which has the old API. The rewrite you’re looking at is merged into main but not released yet. It’ll be a major version (6.0) and will be released in the coming week or so. getCredentials is a new API option in the rewrite, in 5.1.0 the equivalent STS hook is getTemporarySecurityCredentials . Also you can check uppy docs which are based on the old API

I also have a couple of questions to help me point you to the right approach.

  • Does the token need to be scoped to an exact key, or a prefix would be fine too ? (e.g. uploads/${userId}/*)? Prefix-scoping is well supported, exact-key scoping is not, since the credentials callback receives no file context and the result is cached across files.
  • Are you trying Multipart or single-part uploads? There are different hooks for both in the old API

Thank you for the quick reply. Will the new major version 6.0 be backward-compatible with the current API, or else will the version 5 branch continue to be supported? It seems we will need to decide in the short run which version to develop with.

To answer your questions:

Does the token need to be scoped to an exact key, or a prefix would be fine too

A user-specific prefix may be acceptable…can you point me to an example of how that would be done with getTemporarySecurityCredentials?. We could also use the presigned URL approach if needed, which I have used with other apps in the past (not via Uppy). I was just intrigued by the STS option, which appears simpler as long as we can sufficiently control the scope of the tokens.

Are you trying Multipart or single-part uploads

Multipart uploads. Our use case is submission of multi-GB data files direct to S3 as part of a form that includes additional file metadata. My hope is that we can combine the Uppy form and S3 plugins to achieve this, by uploading the files during form submission and then attaching the uploaded object keys as fields in the form which is sent on upload completion to a backend endpoint which triggers processing of the data.

Thank you for the quick reply. Will the new major version 6.0 be backward-compatible with the current API, or else will the version 5 branch continue to be supported? It seems we will need to decide in the short run which version to develop with.

Hello! No, 6.0 will not be backward compatible it’s a deliberate breaking rewrite. The plugin’s configuration is reduced to three mutually exclusive signing modes (getCredentials, signRequest, companionEndpoint), and the per-operation hooks (createMultipartUpload, signPart, listParts, etc.) are removed, along with getTemporarySecurityCredentials its replacement in the new API is getCredentials. The goal was to simplify the plugin and make it easier to maintain. You can see the full before/after in the migration guide ( unreleased )

Thanks for the details on your use case. I’ll look into how the backend-generated key flow fits into the rewrite and possibly add an example for it. Regarding whether the version 5 branch will continue to be supported, I’ll have to check with the team on that.

Hello @jvolkening,

Uppy 6.0 has been released! Check out the Uppy 6.0 blog post and the full migration guide.

Regarding your use case:

signRequest mode is built for what you’re describing. Your server signs one URL per S3 operation, so each URL is scoped to a single object key, and your backend is the one choosing that key.

As of @uppy/aws-s3 6.1.0, the signer can return the key it used alongside the URL, and Uppy will use that key for the rest of the upload, which addresses your second point.

You can find the full request/response shape and the table of operations you need to sign here: AWS S3 signRequest.

The client-side proposal is documented here: AWS S3 generateObjectKey.

You can also refer to the signer implementation in the Node.js example.

Let us know if you face any issues.

Many thanks for your guidance… I agree that using presigned URLs seems the best approach for our use case and we will proceed accordingly. Thank you for the heads-up on release 6.0 and we will begin working it into our development.