Dynmap-Forge/Fabric

Dynmap-Forge/Fabric

888k Downloads

Support temporary AWS credentials

mbarneyjr opened this issue ยท 2 comments

commented

There are two main types of AWS credentials you can use to call AWS APIs:

  • long-term credentials (in the form of an IAM User's AccessKeyId and SecretAccessKey)
  • temporary credentials (in the form of an IAM Role session's AccessKeyId, SecretAccessKey, and SessionToken)

AWS recommends using temporary credentials as a best practice where possible. AWS SDKs generally have/check for these credentials automatically from a few different locations (environment variables, EC2 instance credentials, ECS provider credentials, directly into the SDK client instantiation, etc). In my use case, I'd like to be able to use the AWS ECS execution role directly. With my limited understanding of Java, it seems you're taking the direct SDK client instantiation approach, but are omitting the session token component that would be used in temporary credentials.

I don't know much about Java or the AWS Java SDK, but it seems like AWSS3MapStorage.java is built to use the values specified in configuration (or environment variables):

        access_key_id = core.configuration.getString("storage/aws_access_key_id", System.getenv("AWS_ACCESS_KEY_ID"));
        secret_access_key = core.configuration.getString("storage/aws_secret_access_key", System.getenv("AWS_SECRET_ACCESS_KEY"));
        
        ...
        
                        c = new DefaultS3ClientBuilder()
                        	    .credentialsProvider(() -> AwsBasicCredentials.create(access_key_id, secret_access_key))
                        	    .region(Region.fromString(region))
                        	    .httpClient(URLConnectionSdkHttpClient.create())
                        	    .build();

According to the Java SDK documentation:

To make requests to Amazon Web Services, you must supply AWS credentials to the AWS SDK for Java. You can do this in the following ways:

  • Use the default credential provider chain (recommended).
  • Use a specific credential provider or provider chain (or create your own).

Proposed Change:

I think the best way to support temporary credentials would be to omit the .credentialProvider() call if the long-term credentials are not found in the config so that the client would use the default credential provider chain.

  • Dynmap Version: 3.4-beta-5-806
  • Server Version: Spigot 1.19.1-R0.1
  • Server Host (if applicable): Self-hosted on AWS ECS (Fargate)
  • I have looked at all other issues and this is not a duplicate
  • I have been able to replicate this
commented

Understand the 'best practice', but the temporary role credential you are taking about would be only really usable when running in an EC2 or ECS type environment. That would be fine, but I'm not using the AWS SDK, as it would more than double the size of Dynmap (besides any issues it might create with other mods - I tried rebasing it, and it blew chunks, so no safe way to add AWS SDK to a server without it being a 'shared' library versus a mod-specific one) - I'm using the s3lite package (a fork, as it needed some tweaks to be usable on current java, at https://github.com/webbukkit/s3-lite), so unless that supports it, someone (not me - almost no way this will reach top of priority list, given how little time I have to work on Dynmap these days) will need to add the implementation (there are VERY few S3 users at this point, so don't expect much priority here).

I'll given s3-lite a look tonight to see if it happens to support it: if so, it would probably be easy enough.

commented

Interesting, I missed that it was using a third-party library (as someone who uses the AWS SDK in a few other languages, it's definitely the largest part of many projects I work on, so totally understand wanting to keep deployment artifact size down).

The AWS SDKs are what implement calling up the provider chain for various credential sources, and looking at the original s3-lite repo it appears to be built to use long-term credentials only. I don't see it pulling in a session token or calling against the EC2 metadata endpoint anywhere, so it's probably a steep uphill battle to implement support for that. No worries if this issue gets closed! Thanks for the great mapper!