Skip to content

Supporting file uploads when running on AWS should allow us not to configure S3_REGION, S3_KEY_ID, and S3_KEY_SECRET #11

@wmartins

Description

@wmartins

Hi there!

We're running Interval Server on AWS ECS and we're currently getting some issues while trying to set up file uploads. The server requires us to pass S3_REGION, S3_KEY_ID, and S3_KEY_SECRET, but that should not be necessary when running it on AWS, as one can leverage using the task IAM role in order to access S3.

Some references:

Current workaround

Our current workaround for this is to patch the code and remove the part where it sets the credentials for S3:

credentials: {
accessKeyId: env.S3_KEY_ID,
secretAccessKey: env.S3_KEY_SECRET,
},

After installing interval-server, we're sed-ing dist/src/server/utils/uploads.js:

sed -i -e '/credentials: {/{N;N;N;d;}' "/usr/local/lib/node_modules/@interval/server/dist/src/server/utils/uploads.js"

This simply removes setting the credentials, letting the SDK resolve the credentials dynamically.

Possible solution

Ideally, we should be able to specify only the S3_BUCKET environment variable, and let the other options (S3_REGION, S3_KEY_ID, and S3_KEY_SECRET) be optional. This way, if they're present in the environment, we can use them, otherwise, we let the SDK resolve the credentials dynamically.

Something like this should probably work, although I haven't tested with this code exactly:

diff --git a/src/server/utils/uploads.ts b/src/server/utils/uploads.ts
index e85e31c..0629555 100644
--- a/src/server/utils/uploads.ts
+++ b/src/server/utils/uploads.ts
@@ -1,5 +1,6 @@
 import {
   S3Client,
+  S3ClientConfig,
   PutObjectCommand,
   GetObjectCommand,
   DeleteObjectsCommand,
@@ -24,6 +25,24 @@ function isS3Available(env: any): env is {
   )
 }
 
+function getS3ClientConfig(env: any): S3ClientConfig {
+  const config: S3ClientConfig = {
+    region: env.S3_REGION,
+  }
+
+  if (
+    typeof env.S3_KEY_ID === 'string' &&
+    typeof env.S3_KEY_SECRET === 'string'
+  ) {
+    config.credentials = {
+      accessKeyId: env.S3_KEY_ID,
+      secretAccessKey: env.S3_KEY_SECRET,
+    }
+  }
+
+  return config
+}
+
 export const S3_UPLOADS_ENABLED = isS3Available(env)
 
 function getS3Client() {
@@ -33,13 +52,7 @@ function getS3Client() {
     )
   }
 
-  return new S3Client({
-    region: env.S3_REGION,
-    credentials: {
-      accessKeyId: env.S3_KEY_ID,
-      secretAccessKey: env.S3_KEY_SECRET,
-    },
-  })
+  return new S3Client(getS3ClientConfig(env))
 }
 
 export async function getIOPresignedUploadUrl(key: string): Promise<string> {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions