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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions