-
-
Notifications
You must be signed in to change notification settings - Fork 9.2k
Description
Bug report
Describe the bug
When using an IAM role with strapi for the AWS upload plugin, permission is denied when attempting to configure the credentials.
Specifically, in this instance, I am using an IAM role within a pod in kubernetes using IAM Roles for Service Accounts. This automatically injects two env vars: AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN. I have confirmed for sure these two values exist, additionally I have verified I can perform actions against the named S3 bucket using the AWS cli within the same pod with no issue (or additional configuration needed).
This is using strapi 3.6.1 and strapi-provider-upload-aws-s3 v3.6.3
Steps to reproduce the behavior
- Configure an IAM role within a kubernetes pod (Realistically, an EC2 instance with an instance profile should provide a similar interface)
- Configure the s3 plugin with a configuration similar to (Note: I've also confirmed
S3_ASSETS_BUCKETis the proper value):
var AWS = require('aws-sdk');
module.exports = ({ env }) => ({
upload: {
provider: 'aws-s3',
providerOptions: {
credentials: new AWS.TokenFileWebIdentityCredentials(),
region: env('AWS_REGION') || 'us-west-2',
params: {
Bucket: env('S3_ASSETS_BUCKET'),
},
},
},
});
- Attempt to upload an asset in the strapi admin UI
- Observe an error in the strapi logs similar to:
[2021-06-11T18:52:13.763Z] [2021-06-11t18:52:13.761z] error AccessDenied: Access Denied
at Request.extractError (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/services/s3.js:718:35)
at Request.callListeners (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:116:18)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:38:9)
[2021-06-11T18:52:13.764Z] error Error: Internal Server Error
at convertToStrapiError (/srv/app/node_modules/strapi-plugin-upload/errors.js:38:26)
at Object.upload (/srv/app/node_modules/strapi-plugin-upload/config/functions/bootstrap.js:35:11)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async Object.uploadFileAndPersist (/srv/app/node_modules/strapi-plugin-upload/services/Upload.js:154:5)
at async Promise.all (index 0)
at async Object.upload (/srv/app/node_modules/strapi-plugin-upload/services/Upload.js:140:12)
at async uploadFiles (/srv/app/node_modules/strapi-plugin-upload/controllers/upload/admin.js:187:27)
at async Object.upload (/srv/app/node_modules/strapi-plugin-upload/controllers/Upload.js:65:5)
at async /srv/app/node_modules/strapi/lib/middlewares/router/utils/routerChecker.js:79:22
at async /srv/app/node_modules/strapi-utils/lib/policy.js:68:5
at async /srv/app/node_modules/strapi/lib/middlewares/parser/index.js:48:23
at async /srv/app/node_modules/strapi/lib/middlewares/xss/index.js:26:9
Expected behavior
Assets are uploaded using the IAM role to the S3 bucket configured.
Screenshots
Code snippets
Our plugin config:
var AWS = require('aws-sdk');
module.exports = ({ env }) => ({
upload: {
provider: 'aws-s3',
providerOptions: {
credentials: new AWS.TokenFileWebIdentityCredentials(),
region: env('AWS_REGION') || 'us-west-2',
params: {
Bucket: env('S3_ASSETS_BUCKET'),
},
},
},
});
System
- Node.js version:
v14.15.3(Based on strapi-base image) - NPM version:
6.14.9 - Strapi version:
3.6.1 - Database: Postgres
- Operating system: Debian 9 (Based on strapi-base image)
Additional context
The AWS Node SDK seems to indicate these vars should be read in by virtue of using AWS.TokenFileWebIdentityCredentials(): https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/TokenFileWebIdentityCredentials.html
This class will read filename from AWS_WEB_IDENTITY_TOKEN_FILE environment variable or web_identity_token_file shared config variable, and get the OIDC token from filename. It will also read IAM role to be assumed from AWS_ROLE_ARN environment variable or role_arn shared config variable. This provider gets credetials using the AWS.STS.assumeRoleWithWebIdentity() service operation
For fun and profit, I also tried switching the credentials line to:
credentialProvider: new AWS.TokenFileWebIdentityCredentials(),
That threw an even more ... interesting... error haha:
[2021-06-11T19:07:58.015Z] error TypeError: self.credentialProvider.resolve is not a function
at Config.getCredentials (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/config.js:423:31)
at Request.VALIDATE_CREDENTIALS (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/event_listeners.js:81:26)
at Request.callListeners (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:102:18)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/state_machine.js:14:12)
at Request.runTo (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:408:15)
at Request.send (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/request.js:372:10)
at ManagedUpload.nextChunk (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/s3/managed_upload.js:487:51)
at ManagedUpload.fillBuffer (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/s3/managed_upload.js:417:12)
at ManagedUpload.send (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/s3/managed_upload.js:201:33)
at features.constructor.upload (/srv/app/node_modules/strapi-provider-upload-aws-s3/node_modules/aws-sdk/lib/services/s3.js:1292:50)
at /srv/app/node_modules/strapi-provider-upload-aws-s3/lib/index.js:24:14
at new Promise (<anonymous>)
at Object.upload (/srv/app/node_modules/strapi-provider-upload-aws-s3/lib/index.js:21:16)
[2021-06-11T19:07:58.016Z] error Error: Internal Server Error
at convertToStrapiError (/srv/app/node_modules/strapi-plugin-upload/errors.js:38:26)
at Object.upload (/srv/app/node_modules/strapi-plugin-upload/config/functions/bootstrap.js:35:11)
at async Object.uploadFileAndPersist (/srv/app/node_modules/strapi-plugin-upload/services/Upload.js:154:5)
