Best way to lock bucket item behind authentication?

0

I have an application that sends audio files to a bucket. I then want users to be able to access these audio files attached in a ticket. But of course I want the users to authenticate before accessing the file.

The upload now returns me: https://bucket.s3.eu-central-1.amazonaws.com/RECORDING-478468.mp3 , I was hoping to embed this url to the ticket so users can use this to access the file. Is there a way to restrict what users can use the URL and have them authenticate? As far as I can see it is either public, locked, or programmatic access via CDK's or CLI. Not after clicking the url.

I also thought about using pre signed urls, but I want the file to be available for longer and also thought it was unsafe to store voice recordings there for a longer time.

Any advice?

3 Answers
0

You can add authentication to S3 via the AWS Cognito service.

Here is the link to the documentation: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_cognito-bucket.html

AWS
vtjean
answered a year ago
0

You can use Amazon CloudFront signed URLs.

You can distribute private content using a signed URL that is valid for a short time—possibly for as little as a few minutes or for a longer time, possibly for years. Check out below link for more info.

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html

profile pictureAWS
answered a year ago
0

There are two things necessary to control access, authentication and then authorization. Authentication is how you "know" your users. You haven't mentioned how this works for you today, but without a way to convey that trust to S3 you won't be able to start the authorization process.

It's not possible to answer how to authenticate your users in the scope of this answer because that is dependent on your relationship with your users. If you already have a way of authenticating them, then you can start there.

S3 only supports one type of authentication natively, and that is AWS access credentials. You need to bridge your authentication to the S3 recognized form of authentication.

Depending on your authentication method, you may have other tools to help bridge authentication to AWS access credentials. AWS Cognito is one example which would allow direct communication to S3 without signing or relays.

But let's say that's not practical for your scenario. I can outline the general solution space that remains.

You have a two major sets of options on how to bridge authentication methods. There are request signing mechanisms, and then there are message relay mechanisms. Signing mechanisms have the advantage of not requiring a service you design to relay the bytes of the objects retrieved. Relaying the bytes is practical for smaller volumes, but at larger volumes may decrease efficiency and introduce scalability challenges that you would rather be handled by a service that was already designed to handle that scale (S3 or CloudFront being the two I'll discuss).

If you choose the message relay method, you host a service, your users make requests to it, and your service has access to AWS credentials (temporary credentials recommended). You use those credentials to make requests on behalf of your user. You can perform authorization via custom methods and have S3 trust your service. S3 would in this case allow your service to retrieve any data, but your service wouldn't send any requests that weren't authorized. It is possible to have authorization still done by S3, but that would be a more complex topic, so I'll avoid discussing it here.

If you choose the signing method, you host a service, your users make requests to it, and that service returns signed requests that your users then forward on to another service. Your service has to perform authorization for the users requests before returning signed requests using the authentication method you have available. If your service is serving HTTP requests, you can also use redirects. You'll need to handle Cross-Origin Resource Sharing (CORS) for a browser to accept this type of redirect.

For S3 presigned URLs these are signed with AWS access credentials. User who receive these aren't able to change any of the headers, and there is an expiration time. Generally the model here is that the presigned URLs should be used quickly, as it's a stand-in for direct access. If these users need to access the URL again, they can requested again.

For CloudFront, Signed URLs, you control a set of public/private key pairs and use these to sign request URLs. You have more flexibility here as to how long a signed URL would be valid.

Now, all this said, the situation you describe, where your trying to embed a link in a ticket, makes me uncertain that you have access to the authentication information of your users at all, and that the only authentication you have is that they managed to land on the page where you want to embed the link.

While it's best to know your users for the entire flow, if you are in this situation in which you only have that information, you can create a CloudFront Signed URL and embed it directly, rather than a link to a service that validates authentication and authorization. But keep in mind that the URL there wouldn't retain any authentication or authorization controls.. if users forward the content that contains the link, it would be like them forwarding the content of the link too.

You'll have to evaluate if that fits the use case you have in mind. If you trust the users who have access to the ticketing system highly, and the content from the link is not too sensitive, it might be acceptable, but be sure to evaluate the sensitivity and your expectation of user behavior. If you're uncertain, I'd suggest a solution with lower expirations, and more live authentication processes.

profile pictureAWS
answered a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions