0

As a service provider, I allow logged in users to upload documents to a web server, and upload it to S3. The logged in user should subsequently be able to view his own documents, and I want to serve it directly from S3, with some token-based authentication per request.

I thought that this was a pretty simple and standard use case for S3, but I am unable to find a standard way to this.

Does S3 effectively support per request authentication at object level, and what is the "correct" or "standard" way to do this.

I have read some documentation for STS, but am not able to find a clear way to solve this.

Pre signed urls almost works; the only difficulty is that that it seems to only work with a pre-set expiration time, and "logout" is not supported.

3 Answers3

0

Would it be possible to grant the user an IAM role? If so, you can scope the roles so that each user can only see objects that begin with their prefix, e.g. username/*.

Each user's IAM role will grant them only access to objects whose keys begin with the specified prefix.

The other option would be to use lambda functions to generate pre-signed urls for the user on a per request basis (with very short lived time), hence removing the need for logout, (i.e user request a file, and gets redirected by lambda to the pre-signed url per request).

To the point though, there isn't a 'right' way of doing this as far as I know, and there might be many other options I'm not aware of either.

keithRozario
  • 3,571
  • 2
  • 12
  • 24
  • IAM roles are normally limited to 1000, right? The number of user accounts could be arbitrary. After reading whatever is available, it seems to me that S3 just does not support authentication at object level for logged in users in a scalable manner. – ranban282 Sep 11 '20 at 04:59
  • They do. It's called [shared signature](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html), where your web app would sign a URL that would be valid for some given time. The web app hands this URL to the client. – vidarlo Oct 05 '21 at 16:05
0

The main issue looks like you want to give N number of users direct access to the S3 objects. Bear in mind that S3 is designed to be a 'basic' file store. It is normally used with other layers/systems. Additionally it is generally better to avoid exposing anything to do with s3, bucket URL and worse bucket structure will be exposed if you allow direct connections.

There are a couple ways to control access you might consider, they both involve putting something in front of S3:

  1. Set up Cloudfront (or any other CDN) and restrict direct S3 access to only the CDN. This will allow you to make use of pre-signed URLs and pre-signed cookies (https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html)
  2. Set up a Lambda (or any other server side controller) and proxy all requests through it. Again this limits direct access to the buckets and allows the lambda to do authZ and authN

Also the issue you mentioned with pre-signed url and log out. Using the methods above will allow you to use very short pre-signed timeouts avoiding the need for logout etc.

TrickyDupes
  • 2,809
  • 1
  • 13
  • 27
0

I want to serve it directly from S3

How important is that? Because it's a lot easier if you drop that goal. As other answers have mentioned, S3 is a simple data store, not designed for complicated access patterns and so forth. Additionally, you ask about authentication (possibly you meant authorization?) at the object layer, but the only way that would work with S3 is to give all your users their own IAM users; Amazon doesn't know anything about your user account DB.

So, what if you drop the requirement that the files are served straight from S3? You should be able to, since you already have a server that your users authenticate to, right? Heck, it even already handles the files, just only on upload. So, relay downloads though your server too. You know what files each user downloaded, so authorization is easy. You don't expose direct access to S3, so no need to use signed links or similar. You control session management in your service, so logout is just whatever your current logout system is.

Only real downside, aside from needing to develop the download interface/API, is that it will increase network throughput of your server. That seems like probably a worthwhile trade to me, but if you disagree... signed links with very short lifetimes are a pretty simple approach that should work fine.

CBHacking
  • 40,303
  • 3
  • 74
  • 98