0

I'm encountering an issue where my ECS task generates presigned URLs for objects in S3, but the generated URLs are invalid. I consistently receive an "InvalidToken" error when attempting to access the S3 objects using these URLs.

Here's the context:

ECS Setup:

Running in Fargate.

Task role has the following IAM policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:\*",
                "s3-object-lambda:\*"
            ],
            "Resource": "\*"
        }
    ]
}

ECS task and S3 bucket are in the same AWS region.

ECS task has network connectivity to S3.

Code:

import os
import boto3
from botocore.client import Config

def get_signed_url(s3_key, bucket_name=None, region_name=None):
    """
    Generates a presigned URL for an S3 object.

    Args:
        s3_key (str): The key of the S3 object.
        bucket_name (str, optional): The name of the S3 bucket.
            Defaults to the value of the MY_BUCKET_NAME environment variable.
        region_name (str, optional): The AWS region.
            Defaults to the value of the AWS_REGION environment variable, or 'eu-central-1'.

    Returns:
        str: The presigned URL, or None on error.
    """
    region = region_name or os.getenv("AWS_REGION", "eu-central-1")
    bucket_name = bucket_name or os.getenv("MY_BUCKET_NAME")

    if not bucket_name:
        print("Error: MY_BUCKET_NAME environment variable is not set.")
        return None

    try:
        s3 = boto3.client(
            's3',
            region_name=region
        )
        signed_url = s3.generate_presigned_url(
            "get_object",
            Params={"Bucket": bucket_name, "Key": s3_key},
            ExpiresIn=3600
        )
        return signed_url
    except Exception as e:
        print(f"Error generating presigned URL: {e}")
        return None

if __name__ == "__main__":
    # Example usage in ECS
    s3_key = "charts/your-dynamic-key.png"  # Replace with your actual key
    url = get_signed_url(s3_key)
    if url:
        print(url)
    else:
        print("Failed to generate presigned URL.")

The MY_BUCKET_NAME and AWS_REGION environment variables are set in my ECS task definition.

The S3 object exists in the specified bucket and key.

Troubleshooting Steps Taken:

Verified that the ECS task role has the necessary S3 permissions (including s3:GetObject).

Confirmed that the ECS task and S3 bucket are in the same AWS region.

Checked ECS task network connectivity to S3.

Tested the code locally, and it works without any issues.

Ensured the S3 key is correct.

The problem persists only when the code is running in ECS. The ECS task generates the presigned URL, but the generated URL is invalid, resulting in an "InvalidToken", "The provided token is malformed or otherwise invalid." error when attempting to access the S3 object. What could be causing this error in this specific environment, and how can I resolve it?

2
  • It is likely that the short-lived access keys your ECS task is using to sign the S3 URL are expiring quickly. So when you go to use the URL AWS checks the key it was signed with, and sees that it is no longer valid, thus giving you an InvalidToken error.
    – Mark B
    Commented 12 hours ago
  • stackoverflow.com/questions/63068057/… This has the explanation how to avoid it
    – Vikram S
    Commented 10 hours ago

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.