Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Thumbor to access S3 resources using AWS Managed Policies #35

Closed
tschaffter opened this issue Sep 20, 2024 · 17 comments
Closed

Enable Thumbor to access S3 resources using AWS Managed Policies #35

tschaffter opened this issue Sep 20, 2024 · 17 comments

Comments

@tschaffter
Copy link

Thank you for developing and maintaining this Thumbor Docker image! It's been a great help to us in our project, and we appreciate all the effort you've put into it.

We encountered an issue while attempting to provide the Docker container on AWS ECS access to an S3 bucket using an AWS managed policy instead of passing AWS credentials directly. When we try to access an image, Thumbor throws an InvalidAccessKeyId error. This happens when attempting to fetch an image from within the container.

Error Details:

2024-09-20 17:24:52 thumbor:ERROR ERROR: Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/thumbor/handlers/__init__.py", line 212, in get_image
    result = await self._fetch(self.context.request.image_url)
File "/usr/local/lib/python3.10/site-packages/thumbor/handlers/__init__.py", line 884, in _fetch
    loader_result = await self.context.modules.loader.load(
File "/usr/local/lib/python3.10/site-packages/thumbor_aws/loader.py", line 89, in load
    status_code, body, last_modified = await client.get_data(
File "/usr/local/lib/python3.10/site-packages/thumbor_aws/s3_client.py", line 143, in get_data
    response = await client.get_object(Bucket=bucket, Key=path)
File "/usr/local/lib/python3.10/site-packages/aiobotocore/client.py", line 371, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidAccessKeyId) when calling the GetObject operation: The AWS Access Key Id you provided does not exist in our records.

Steps to Reproduce:

  1. Configure Thumbor to use an AWS managed policy for S3 access.
  2. Try to access an image hosted in the S3 bucket.
  3. Observe the InvalidAccessKeyId error in the logs.

Expected Behavior:
Thumbor should successfully access the S3 bucket using the permissions granted by the managed policy, without the need for hardcoded AWS credentials.

Actual Behavior:
Thumbor fails to access the S3 bucket and throws an InvalidAccessKeyId error.

Suggested Solution:
It seems that Thumbor might not be properly configured to use IAM roles or managed policies. We suggest updating the Thumbor configuration to fully support AWS managed policies for S3 access. This could involve:

  1. Ensuring that the AWS SDK within Thumbor is correctly set up to use the IAM role or managed policy assigned to the ECS task/container.
  2. Verifying that Thumbor is not defaulting to looking for static credentials in the environment or configuration files.

Environment:

  • Thumbor Version: beeyev/thumbor-s3:7.4-alpine
  • Deployment: ECS Fargate with IAM roles

Additional Context:
This issue prevents us from using the recommended security practices for AWS deployments, where sensitive credentials should not be hardcoded or passed explicitly.

We would appreciate any guidance on how to configure Thumbor to work with AWS managed policies, or if this could be implemented as a feature.

@tschaffter
Copy link
Author

tschaffter commented Sep 20, 2024

@tschaffter
Copy link
Author

tschaffter commented Sep 20, 2024

I can successfully download an image in the S3 bucket with the AWS CLI from inside the Thumbor container. This command is run right after installing the AWS CLI client, without configuring any AWS profile or credentials thanks to the AWS managed policy that we have set in place:

/app # aws s3 cp s3://BUCKET_NAME/img/triforce.png triforce.png
download: s3://BUCKET_NAME/img/triforce.png to ./triforce.png

@tschaffter
Copy link
Author

@beeyev There is one difference between the config example provided by thumbor_aws and the config file generated by the Docker image. The former uses None values while the latter specifies 'None'.

thumbor_aws uses None: https://github.com/thumbor/thumbor-aws/tree/main?tab=readme-ov-file#loader

This image generates a config file that includes 'None': from the actual config file inside the container: /usr/local/etc/thumbor.conf:

## Secret access key for S3 Loader.
## Defaults to: None
AWS_LOADER_S3_SECRET_ACCESS_KEY = 'None'

## Access key ID for S3 Loader.
## Defaults to: None
AWS_LOADER_S3_ACCESS_KEY_ID = 'None'

I think that thumbor_aws evaluates the value as the string "None" and not as the None value.

@beeyev
Copy link
Owner

beeyev commented Sep 25, 2024

Thank you, I will check it!

@tschaffter
Copy link
Author

I can now confirm that specifying None instead of 'None' solved the issue.

@beeyev
Copy link
Owner

beeyev commented Sep 28, 2024

@tschaffter
I built a new test docker image with possible fix ghcr.io/beeyev/thumbor-s3:debian-test
could you please check if it works?

@tschaffter
Copy link
Author

I will give it a try today. Thanks!

@tschaffter
Copy link
Author

tschaffter commented Sep 30, 2024

@beeyev I get this error when stepping into the container and fetching an image with wget.

Event Time Message
2024-09-30T16:04:34.403Z 2024-09-30 16:04:34 thumbor:ERROR ERROR: Traceback (most recent call last):
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor/handlers/init.py", line 214, in get_image
2024-09-30T16:04:34.403Z result = await self._fetch(self.context.request.image_url)
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor/handlers/init.py", line 916, in _fetch
2024-09-30T16:04:34.403Z loader_result = await self.context.modules.loader.load(
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor_aws/loader.py", line 89, in load
2024-09-30T16:04:34.403Z status_code, body, last_modified = await client.get_data(
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor_aws/s3_client.py", line 141, in get_data
2024-09-30T16:04:34.403Z async with self.get_client() as client:
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor_aws/s3_client.py", line 95, in get_client
2024-09-30T16:04:34.403Z region_name=self.region_name,
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/thumbor_aws/s3_client.py", line 46, in region_name
2024-09-30T16:04:34.403Z "region_name", self.config.AWS_STORAGE_REGION_NAME
2024-09-30T16:04:34.403Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-09-30T16:04:34.403Z File "/usr/local/lib/python3.12/site-packages/derpconf/config.py", line 225, in getattr
2024-09-30T16:04:34.403Z raise AttributeError(name)
2024-09-30T16:04:34.403Z AttributeError: AWS_STORAGE_REGION_NAME. Did you mean: 'AWS_LOADER_REGION_NAME'?
2024-09-30T16:04:34.403Z 2024-09-30 16:04:34 thumbor:ERROR [BaseHandler] get_image failed for url triforce.png. error: AWS_STORAGE_REGION_NAME
2024-09-30T16:04:34.403Z 2024-09-30 16:04:34 tornado.access:ERROR 500 GET /unsafe/600x600/triforce.png (127.0.0.1) 4.49ms

I do not specify the environment variable AWS_STORAGE_REGION_NAME when starting the container.

# echo $AWS_STORAGE_REGION_NAME

This Key-Value is not specified in the config file because this PR only prints some KVs if their key is specified.

$ cat /usr/local/etc/thumbor.conf
...

################################# AWS Storage ##################################
# Documentation: https://github.com/thumbor/thumbor-aws#storage

## Region where thumbor's objects are going to be stored.
## Defaults to: 'us-east-1'


## S3 Bucket where thumbor's objects are going to be stored.
## Defaults to: 'thumbor'


@beeyev
Copy link
Owner

beeyev commented Sep 30, 2024

What configuration do you use? Can you provide the values please

@tschaffter
Copy link
Author

tschaffter commented Sep 30, 2024

Here are the environment variables passed to the Thumbor container deployed with AWS CDK (dev deployment):

thumbor_props = ServiceProps(
    "openchallenges-thumbor",
    8889,
    512,
    "ghcr.io/beeyev/thumbor-s3:debian-test",
    {
        "LOG_LEVEL": "info",
        "PORT": "8889",
        "LOADER": "thumbor_aws.loader",
        "AWS_LOADER_REGION_NAME": "us-east-1",
        "AWS_LOADER_BUCKET_NAME": bucket_stack.openchallenges_img_bucket.bucket_name,
        "AWS_LOADER_S3_ENDPOINT_URL": "http://s3.us-east-1.amazonaws.com",
        "AWS_LOADER_ROOT_PATH": "img",
        "STORAGE": "thumbor.storages.file_storage",
        "FILE_STORAGE_ROOT_PATH": "/data/storage",
        "RESULT_STORAGE": "thumbor.result_storages.file_storage",
        "RESULT_STORAGE_FILE_STORAGE_ROOT_PATH": "/data/result_storage",
        "RESULT_STORAGE_STORES_UNSAFE": "True",
        "RESULT_STORAGE_EXPIRATION_SECONDS": "2629746",
        "SECURITY_KEY": secrets["SECURITY_KEY"],
        "ALLOW_UNSAFE_URL": "True",
        "QUALITY": "100",
        "MAX_AGE": "86400",
        "AUTO_PNG_TO_JPG": "True",
        "HTTP_LOADER_VALIDATE_CERTS": "False",
    },
)

@beeyev
Copy link
Owner

beeyev commented Sep 30, 2024

@tschaffter
I just updated the docker image ghcr.io/beeyev/thumbor-s3:debian-test
Could you please pull the update and try again?

@tschaffter
Copy link
Author

@beeyev The latest image works!

@beeyev
Copy link
Owner

beeyev commented Sep 30, 2024

Amazing! I will prepare the new release tomorrow

@tschaffter
Copy link
Author

Thanks so much for fixing that so quickly.

beeyev added a commit that referenced this issue Oct 1, 2024
Config update, fix issue #35 (#36)
@beeyev
Copy link
Owner

beeyev commented Oct 1, 2024

@tschaffter I updated the docker image with the fix.
Thank you for your help solving this issue 👍

@tschaffter
Copy link
Author

@beeyev Could you please update the image beeyev/thumbor-s3:7.7-alpine too (last updated 10 months ago)? I need SVG to PNG conversion, which is not available in the slim version.

https://hub.docker.com/r/beeyev/thumbor-s3/tags
https://github.com/beeyev/thumbor-s3-docker/pkgs/container/thumbor-s3

@beeyev
Copy link
Owner

beeyev commented Oct 1, 2024

@tschaffter I deprecated this image, because full-featured thumbor instance can't work stable on alpine linux.
You need to use debian if you want all features, or you can use slim-alpine if you are fine with the basic functionality.

beeyev/thumbor-s3:debian
beeyev/thumbor-s3:slim-alpine
beeyev/thumbor-s3:7-debian
beeyev/thumbor-s3:7-slim-alpine
beeyev/thumbor-s3:7.7-debian
beeyev/thumbor-s3:7.7-slim-alpine

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants