Is an api gateway to s3 the way to go

Hi.

I have a static website coded in angular io. The users on the site should have access to their own s3 buckets. To do this I have created an api gateway with a custom authenticator. Then in the authenticator I can choose which buckets a user has access to. By doing like this.
policy.allowMethod(AuthPolicy.HttpVerb.GET, “/api/s3/bucketname/");
policy.allowMethod(AuthPolicy.HttpVerb.PUT, "/api/s3/bucketname/
”);

Is this the right way to solve this problem. Or is there a smarter solution where my angular solution can go straight to s3 without going through the api gateway and still be restricted to specific buckets?

My users are not added as amazon users. They are only in my own database.

My next step here is to look into if I can go through cloudfront with theese requests. If I understand the pricing correctly that will make the transfer from s3 to cloudfront free. But Im not sure if it goes through the api gateway…

Check out getOpenIdTokenForDeveloperIdentity(), AssumeRoleWithWebIdentity()

Then on this page:
http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html
role id:caller-specified-role-name

I think you’d find it much easier to use a Cognito User Pool and not roll your own authentication.

Ok. Thx for the pointers Ill look into that.

Is it possible to group the users so some users have read access to the same bucket and only one of them is an admin of the bucket?

I also have lambda functions where I also use the api gateway to controll which users are allowed to call the different functions. Is that also something that can be controlled if I use the cognito user pool?

You can set different restrictions like this:

http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_s3_cognito-bucket.html

Rolling your own authentication is a lot of work. Far easier to use a service.

Lamda functions run in their own role. So you should make a specific role for each lambda function that restricts what it can do to a minimum. The Cognito user id is passed as an input variable into the lambda function. Those web authenticated identities are also passed.

The S3 policy variables will not work as you expect them to from lambda. Lamda runs in its own role not as the Cognito user. The policy variables are for when your app directly accesses S3 without lambda in the way.

Thx alot. Ill look into this =)

It sounds like you need an authorizer that is controlling this access.

http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html

I found incognito to be a bit cumbersome, and Auth0 + custom authorizer with a JWT token a bit easier to manage. From there you could use the URL to determine what users have access to and simply route them to the appropriate bucket or path within the bucket.

The authorizer could be written to grant additional permisions or bucket access based on the grants within the JWT token, so you are offloading that complexity to the 3rd party and not having to roll it yourselves.

If you wanted to get clever, you could put your own CloudFront instance infront of the gateway and your S3 bucket. You could then route all ‘GET’ requests directly to your S3 bucket and then route your other method calls to API gateway. You will probably have some things to figure out regarding CloudFront cache, but it could be an effective solution for delivery if cost is a concern.

Matt, you can use AssumeRoleWithWebIdentity() on AWS to exchange your Auth0 JWT token for temporary AWS credentials. Those temp credentials will have a Cognito ID set in them. That exchange process uses a Federation Pool in Cognito.

I do find Cognito to be confusing. There are two pieces to it. User Pools - those function like the Auth0 piece and return JWT tokens. Federation Pools, those are free to use. You give them tokens and they return temporary AWS credentials locked to the role associated with the Federation Pool.

Note there is also AWS support for Developer Authenticated entities, I have not tried working with that yet. That may be how you deal with JWT tokens you made up yourself.