3

I want to generate an s3 link to download a file, the link should be live for at least 6 days. I have tried with options InstanceProfileCredentialsProvider(false)(Which worked only for 24 hours), ProfileCredentialsProvider(doesn't even create a link ), Access Key

Access key of IAM user worked, but this user key will expire after some days so every time I have to change the same in the code and also I think it is not a good practice to expose the key in the code.

Is there any other way I can generate an s3 download link which will expire only after 6 days.

Below is the code snippet:-

AmazonS3 s3Client  = AmazonS3ClientBuilder.standard().withCredentials(new InstanceProfileCredentialsProvider(false))
                    .build();
java.util.Date expiration = new java.util.Date();
long milliSeconds = expiration.getTime();
milliSeconds += 1000 * 60 * 60 * 24 * 7; // Add 7 days.
expiration.setTime(milliSeconds);
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest("s3bucket",
                    "fileLocationpath");
generatePresignedUrlRequest.setMethod(HttpMethod.GET);
generatePresignedUrlRequest.setExpiration(expiration);
link =  s3Client.generatePresignedUrl(generatePresignedUrlRequest);
user3132347
  • 363
  • 1
  • 7
  • 27
  • I strongly recommend using jets3t instead of the bare AWS SDK; it's much less of a pain to deal with. (And use the modern Java 8 time APIs; `now().plus(6, DAYS).toEpochMilli()` would be a lot easier to read.) – chrylis -cautiouslyoptimistic- Dec 17 '19 at 07:39
  • I guess, for Jets3t also required access key and secret key, which I need to give in the code. There I am facing the issue. I don't want to expose the key in the code. – user3132347 Dec 17 '19 at 11:23
  • You need to learn about _externalized configuration_. https://12factor.net/, and Spring Boot (and some similar tools) make this easy for Java applications. – chrylis -cautiouslyoptimistic- Dec 17 '19 at 23:01
  • Sorry, but what is the specific problem? You should generate the pre-signed URL using non-expiring credentials. That way, the pre-signed URL will be valid for the entire period. The application should use its own (permanent) access key to generate the pre-signed URLs. – John Rotenstein Dec 18 '19 at 03:58

1 Answers1

3

The general idea of the way that you implement your solution is the proper way as suggested by AWS.

About the user key that expires after 80 days, as the user keys do not expire automatically and they are valid until you deactivate them, i imagine that this is a process that you set up in order to rotate your credentials for security reasons. That's a very good practice indeed. In order to avoid hard code these credentials in the code, something that is a bad practice, you can just set up your credentials as an environment variable or store them in the AWS credentials file in your instance. By doing this you can then easily rotate them through your deployment pipeline.

You can make the ./aws/credentials configuration through user data, when you start an ec2 instance. You will run "aws configure" and then pass your aws credentials to set them up in your ec2 instance. Ideally you will have a CI/CD pipeline which will automate the whole process instead for doing this manually.

Please see below recommended best practices by AWS:

Presigned URL for s3 buckets - Recommended ways

https://aws.amazon.com/premiumsupport/knowledge-center/presigned-url-s3-bucket-expiration/

AWS access keys best practices

https://docs.aws.amazon.com/general/latest/gr/aws-access-keys-best-practices.html

Configuration and Credential File Settings

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html

Xanthos Symeou
  • 684
  • 5
  • 11
  • I tried to save the credentials in .aws/credentials file and used AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withCredentials(new ProfileCredentialsProvider("profile2")).build(); This is also not working. I wonder why – user3132347 Dec 17 '19 at 11:20
  • What about if the instances get terminated and came up with new instances, we need to set the credentials again for the new instances right. or it will take it up automatically? – user3132347 Dec 17 '19 at 12:09
  • - in order to be sure that you setup the .aws/credentials correctly, download and setup your AWS CLI and then run : "aws configure" in order to setup the ~./aws/credentials file. – Xanthos Symeou Dec 17 '19 at 12:55
  • About the terminated instances, you have to set the credentials again you are correct. Please see updated response above. – Xanthos Symeou Dec 17 '19 at 12:55