node.jsamazon-web-servicesaws-sdkaws-cliaws-sts

Unable to upload to S3 using STS credentials


Describe the bug

I'm trying to integrate STS assumeRole based authentication to upload my files to S3 buckets...

Code Snippet

AWS.config.update({
  region: 'ap-south-1',
  maxRetries: 3,
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  sessionToken: process.env.AWS_SESSION_TOKEN,
})

const roleToAssume = {
  RoleArn: process.env.ASSUME_ROLE_ARN,
  RoleSessionName: 'codebuild',
  DurationSeconds: 900,
}

const sts = new AWS.STS({
  apiVersion: '2011-06-15',
  region: 'ap-south-1',
  endpoint: 'sts.ap-south-1.amazonaws.com',
})
sts.assumeRole(roleToAssume, function (err, assumedRole) {
    if (err) {
      reject__(err)
      console.log('err>>>', err, err.stack)
    } else {
      console.log(
        '🚀 ~ file: uploadTos3.js:30 ~ sts.assumeRole ~ data:',
        assumedRole
      )

      fileArray.map((file) => {
        // Configuring parameters for S3 Object
        const s3 = new AWS.S3({
         accessKeyId: assumedRole.Credentials.AccessKeyId,
      secretAccessKey: assumedRole.Credentials.SecretAccessKey,
      sessionToken: assumedRole.Credentials.SessionToken,
    })
        const S3params = {
          Bucket: process.env.S3_BUCKET,
          Body: fs.createReadStream(file),
          Key: generateFileKey(file),
        }
        s3.upload(S3params, function (err, data) {
          if (err) {
            console.error(err)
          } else {
            console.log(`Assets uploaded to S3: `, data)
          }
        })
      })
      response__()
    }
  })

but everytime sts.assumeRole throwing this error



InvalidClientTokenId: The security token included in the request is invalid
--
823 | at Request.extractError (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/protocol/query.js:50:29)
824 | at Request.callListeners (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
825 | at Request.emit (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
826 | at Request.emit (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:686:14)
827 | at Request.transition (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:22:10)
828 | at AcceptorStateMachine.runTo (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/state_machine.js:14:12)
829 | at /var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/state_machine.js:26:10
830 | at Request.<anonymous> (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:38:9)
831 | at Request.<anonymous> (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:688:12)
832 | at Request.callListeners (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
833 | code: 'InvalidClientTokenId',
834 | time: 2023-05-18T13:59:07.868Z,
835 | requestId: '3bc35552-7494-4605-9380-1fb8743e7d51',
836 | statusCode: 403,
837 | retryable: false,
838 | retryDelay: 62.92943618134528
839 | }

Scenerio-2 Here, Instead of using sts from aws-sdk I'm using aws-cli in docker image & passing assumedRole.Credentials from cli.

Command:
aws sts assume-role --role-arn $ASSUME_ROLE_ARN --role-session-name codebuild

-- Providing Credentials

But here also, I'm not able to use these credentials with aws-sdk like this

        const s3 = new AWS.S3({
          accessKeyId: process.env.AWS_ACCESS_KEY_ID,
          secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
          sessionToken: process.env.AWS_SESSION_TOKEN,
        })
        const S3params = {
          Bucket: process.env.S3_BUCKET,
          Body: fs.createReadStream(file),
          Key: generateFileKey(file),
        }
        s3.upload(S3params, function (err, data) {
          if (err) {
            // Set the exit code while letting the process exit gracefully.
            console.error(err)
            process.exitCode = 1
          } else {
            console.log(`Assets uploaded to S3: `, data)
          }
        })

Here Getting this error


InvalidToken: The provided token is malformed or otherwise invalid.
--
16 | at Request.extractError (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/services/s3.js:711:35)
17 | at Request.callListeners (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
18 | at Request.emit (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
19 | at Request.emit (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:686:14)
20 | at Request.transition (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:22:10)
21 | at AcceptorStateMachine.runTo (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/state_machine.js:14:12)
22 | at /var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/state_machine.js:26:10
23 | at Request.<anonymous> (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:38:9)
24 | at Request.<anonymous> (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/request.js:688:12)
25 | at Request.callListeners (/var/loco/loco/node_modules/.pnpm/aws-sdk@2.1379.0/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
26 | code: 'InvalidToken',
27 | region: null,
28 | time: 2023-05-18T13:44:22.058Z,
29 | requestId: 'CH90H7F00MZ4AYQB',
30 | extendedRequestId: 'SHL6HZeiY9Ts+Iu+RGahpQufpxTigrEmOO0t4ICtlqJ9AjEoREb6pRai4XtfDpxLqiN3VjmrQEM=',
31 | cfId: undefined,
32 | statusCode: 400,
33 | retryable: false,
34 | retryDelay: 0.14215548664469058
35 | }

Expected Behavior

I want to setup STS assumeRole & use those credentials to upload file to S3.

There might be the RoleARN access issue, But I'm unable to identify that as well

Current Behavior

  1. Abel to setup STS assumeRole credentials using aws-cli but unable to use with S3 from aws-sdk
  2. Not able to setup STS assumeRole using aws-sdk

Reproduction Steps

Same as above

I'm writing the code in upload_to_bucket.js file & running the same using Docker node upload_to_bucket.js

Possible Solution

idk, but it would be great help if anyone answer this.

Additional Information/Context

Ping me / Mail me @sanskardahiya98@gmail.com for any further information.

SDK version used

"aws-sdk": "^2.1379.0"

Environment details (OS name and version, etc.)

AWS Codebuild


Solution

  • Above code is correct itself, Issue was due to restricted access, My EC2 machine does not have access to STS,

    It is fixed by providing appropriate access.