'How to Create Presigned S3 URL with a 72 Hour TTL
So far, I am only able to create a pre-resigned URL that is valid for 1 hour.
I tried increasing the duration of the presaged URL to 72 hours directly, but the temporary token that is associated with the URL expires after 1 hour. I know that tokens generated through an IAM role have a maximum duration of 12 hours, but I really need this pre-signed URL to last for 72 hours.
I tried implementing something similar to:
https://github.com/aws/aws-sdk-java/issues/2681
but keep getting an InvalidAccessKeyIdThe AWS Access Key Id you provided does not exist in our records error from AWS after I click on the generated pre-signed URL.
I've read about the AWS Signature Version 4 means to allow the credentials to live for up to 7 days, but would preferably like to implement this as done in the GitHub link I sent above.
Here is some of the logic I have so far (condensed into one block for simplicity)
AWSSecurityTokenServiceClient stsClient = (AWSSecurityTokenServiceClient) AWSSecurityTokenServiceClientBuilder.defaultClient();
AssumeRoleWithWebIdentityRequest request = new AssumeRoleWithWebIdentityRequest()
.withDurationSeconds(43200) // 12 hours is the max.
.withRoleArn(iam)
.withWebIdentityToken("file://" + System.getenv("AWS_WEB_IDENTITY_TOKEN_FILE")) // Not sure about this logic here
.withRoleSessionName("aws-sdk-java-" + System.currentTimeMillis());
AssumeRoleWithWebIdentityResult result = stsClient.assumeRoleWithWebIdentity(request);
basicSessionCredentials = new BasicSessionCredentials(result.getCredentials().getAccessKeyId(),
result.getCredentials().getSecretAccessKey(),
result.getCredentials().getSessionToken());
// Calculate expiration date.
java.util.Date expiration = new java.util.Date();
long expTimeMillis = Instant.now().toEpochMilli();
expTimeMillis += 1000 * 60 * 60 * durationHours;
expiration.setTime(expTimeMillis);
// Set configurations necessary for S3.
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(bucket, key)
.withMethod(HttpMethod.GET)
.withExpiration(expiration);
// Provide custom AWS Credentials that last 72 hours. This means the temporary token is only
// valid for 72 hours and that the pre-signed URL can't have a TTL longer than 72 hours.
generatePresignedUrlRequest.withRequestCredentialsProvider(
new AWSStaticCredentialsProvider(basicSessionCredentials));
URL presignedURL = amazonS3.generatePresignedUrl(generatePresignedUrlRequest);
I am using Helm Charts to deploy my cluster:
My serviceaccount.yaml file:
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Release.Name }}
namespace: {{ .Release.Namespace }}
labels:
account: {{ .Release.Name }}
annotations:
eks.amazonaws.com/role-arn: {{ .Values.aws.iamRole }}
secrets:
- name: {{ .Release.Name }}-s3-token
deployment.yaml file:
volumes:
...
- name: aws-iam-token
projected:
defaultMode: 420
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 259200
path: token
...
containers:
...
env:
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/sample/token
volumeMounts:
- mountPath: /var/run/secrets/eks.amazonaws.com/sample
name: aws-iam-token
...
Supplementary resource:
https://aws.amazon.com/blogs/opensource/introducing-fine-grained-iam-roles-service-accounts/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
