3

Wondering if it's possible to have a webapp upload a file (userid.input.json) to Amazon S3, which triggers a lambda function that reads the file, does some processing, and saves the result as another (userid.output.json).

However userid.output.json should not be immediately accessible to the web application. The webapplication has to complete a Stripe payment and once the payment completes, the web application can access the (userid.output.json) file on amazon s3.

Before I ask how, I figured I'd first ask if this this scenario can be facilitated / architected on AWS?

Approach

Note that this is an update to the question based on more research. It looks like Amazon Cognito will be the perfect tool for signing in users and tying their user credentials to an IAM role that can read and write to S3 buckets.

So once the user is signed in through Amazon Cognito and has the proper credentials then their files can be uploaded to an S3 bucket and processed by a lambda. The result is then written to the same bucket.

Now earlier I suggested writing to a sealed bucket and having a Stripe webhook trigger moving the result from the sealed bucket to an accessible bucket. But it seems this is necessary, per the indication in the answer provided by @Snickers3192.

Once the stripe payment completes the webapp can set a boolean that is used to control access to the output and that completes the cycle?

Part of the rational for having a hidden bucket was that someone might pull the credentials out of the browser and execute them in a different script. I assume this is impossible (Famous last words :) ), but just in case I wrote a follow up question here.

In other words the credentials that are pulled into the client post signin with Amazon Cognito cannot be used to executed scripts outside of the application context?

Approach Part 2

Per my follow up questions it does not appear that relying on state within the webapp for making security decisions is good enough, as someone can probably figure out a way to get the token authentication token and manipulate the applications API directly using a client other than the core app.

So now I'm thinking about it like this:

1) Write the result to the sealed bucket (Processing Lambda)

2) Have the Stripe webhook update the users a transaction record in the users profile indicating payment paid = true (Stripe Lambda)

3) Create another lambda that has access rights to the sealed bucket but will return results only if paid=true. (Access Result Lambda)

So since Stripe is tied to an IAM user that is allowed to update the Application user profile and set paid=true and the sealed bucket can only be accessed by lambda that first checks if paid=true before returning the result, I believe that should guarantee security.

If anyone has a simpler approach please let me know.

Ole
  • 41,793
  • 59
  • 191
  • 359
  • Why would you want to impose limitations on your own webapp? – shmosel Apr 04 '18 at 05:27
  • The general idea is for the lambda to a service then once the computation completes the client in shown some of the results, but not all. In order to get the complete set of results, checkout must first be performed, and then the client can retrieve the entire result set. – Ole Apr 04 '18 at 05:57
  • So restrict what the client has access to, not the webapp. – shmosel Apr 04 '18 at 05:59

1 Answers1

1

This really is more a question of where you want to put the security, which in AWS there are many options, in your application logic which could mean:

  • Lambda/Webapp
  • S3 policies
  • IAM roles/groups

These decisions are usually dictated by where your identity store is kept, and also if you want to keep the notion of AWS users VS. users of your app. My preference is to keep these two pools separate, in that security logic like this is kept in the webapp/lambda and AWS security only deals with what rights developers have to the environment as well as what rights applications themselves have.

This means the webapp can always access the input and output buckets, but it keeps a record in a database somewhere (or makes use of your payment system API) who has paid and who hasn't paid and uses that information to deny or grant access to users. IMO this is a more modular design, and it enables you to lock down your AWS account better and is more clear to developers where security is located. In addition if you do go with IAM/S3 it will be more difficult to run and debug locally.

EDIT: After all your comments and additional security concerns you may also want to consider emailing a short lived URL link to the processed file, so that a user needs both email access as well as knowing their credentials to the application. This will mean even if your access token is stolen at the browser level, without the email access a hacker still can't get the processed file. If you want to be EXTREME SECURITY CORE, have the link that not only is authentication required, but also MFA so that they need to enter in a code which is constantly refreshing as you should have setup for your AWS account when you login.

I'm by no means a security expert but just follow best practices and do your due diligence and you will meet security expectations.

Derrops
  • 7,651
  • 5
  • 30
  • 60
  • Thanks - I updated the question a bit with some more research into Cognito and a follow up question. I seems like once the stripe payment completes we can set a boolean within the application since it is aware that the payment completed, but my only hesitation on that is whether the credentials obtained from Cognito could somehow be fished out and used in a different context outside of the application. – Ole Apr 09 '18 at 03:19
  • great tip in the updated edit! Also made an edit to the question right before I saw your edit. I really like those ideas. I'm not a security expert either, so trying not to get blown up on my first attempt at this :) – Ole Apr 09 '18 at 15:55