2

Summary

I have a platform running in AWS which is exposed via REST APIs backed by AWS Lambda. The platform stores metadata in DynamoDB and content in S3. Users are authenticated by Cognito and are stored in a User Pool. The platform manages permissions to control which users can access (and whether they can modify) which metadata (and therefore the associated content).

I can use STS to exchange users' JWT tokens for STS tokens (using the Cognito Identity Pool) and grant them permission to read or write to a particular object in S3. Creating the STS token is handled by the platform. This works perfectly when accessing S3 directly and appears to be a perfect use case for STS.

Two asides to address some comments:

  • Pre-signed S3 URLs are not secure enough as anyone with the link can access the content
  • I have to upload directly to S3 as I'm not running any servers and Lambdas aren't appropriate to stream my content through due to the temporary space limits in the Lambda (512MB) and the amount of time a request can execute through API Gateway (29 seconds)

I would like to add CloudFront in front of the S3 bucket to benefit from its CDN capabilities; this will reduce data transfer costs if content can be served from the edge rather than retrieving from S3 each time. This is where I am having problems - I do not know how to send the STS token to CloudFront such that it will pass it through to S3.

Question: how do I use STS credentials to read/write from an S3 bucket when it is fronted by CloudFront?

Further details

I have created two roles which can be assumed by STS. One which has s3:ListBucket and one which has s3:PutObject. I've then used Postman to perform GET and PUT requests on my bucket, specifying the access key, secret key and session token from the STS assume-role-with-web-identity call.

Both GET and PUT operations and both work when accessing S3 directly but neither work when using CloudFront. Interestingly I get different errors for GET and PUT.

Error from GET:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AccessDenied</Code>
    <Message>No AWSAccessKey was presented.</Message>
    <RequestId><!-- snip --></RequestId>
    <HostId><!-- snip --></HostId>
</Error>

Error from PUT:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
    <AWSAccessKeyId><!-- snip --></AWSAccessKeyId>
    <StringToSign><!-- snip --></StringToSign>
    <SignatureProvided><!-- snip --></SignatureProvided>
    <StringToSignBytes><!-- snip --></StringToSignBytes>
    <CanonicalRequest><!-- snip --></CanonicalRequest>
    <CanonicalRequestBytes><!-- snip --></CanonicalRequestBytes>
    <RequestId><!-- snip --></RequestId>
    <HostId><!-- snip --></HostId>
</Error>

I have removed some values from the responses but can provide them if they are necessary.

Stuart Leyland-Cole
  • 1,243
  • 7
  • 19
  • 35
  • This is certainly possible but you need to make a lot of changes in CloudFront to pass these parameters to s3 and not change it , you can instead use cloudfront signed url which can be easy. – James Dean Sep 04 '19 at 15:57
  • That's encouraging that it's possible. Do you have a link to the steps required to configure it? I don't think that signed URLs will work for my use case but I will re-read the documentation to verify that. – Stuart Leyland-Cole Sep 04 '19 at 16:10
  • Random curiosity here... If the permissions on the credentials are scoped as you want them, why not just use the credentials with the aws-sdk and let the app work directly with the bucket and avoid CloudFront all-together? – hephalump Sep 04 '19 at 23:58
  • _WHY_ do you wish to use STS credentials? Could you edit your question to describe more of your scenario? STS credentials are not normally passed to clients. It is safer for the backend to perform sensitive operations. In the case of providing private content, the back-end can generate signed URLs to grant access. – John Rotenstein Sep 05 '19 at 00:01
  • John Rotenstein and hephalump: I've updated my question to address your comments, I hope this adds some clarity. – Stuart Leyland-Cole Sep 05 '19 at 10:08

0 Answers0