Preamble
- Central requires config to upload blob media to an external S3 bucket:
S3_SERVER=https://service.com S3_ACCESS_KEY=MY_ACCESS_KEY S3_SECRET_KEY=MY_SECRET S3_BUCKET_NAME=MY_BUCKET
- This mode of authentication, using an access key / secret key pair is not security best practice.
- I have configured IAM role-based auth from my EC2 instance to the S3 as follows.
- Understandably, directly connecting like this does not work with the Minio SDK (requires AWS CLI). But it's possible to connect using temporary credentials generated on connection.
- As ODK Central cannot use S3 without having
S3_ACCESS_KEY
andS3_SECRET_KEY
set, this approach would require adding dummy values, then using a middleware Lambda to generate temporary credentials on connection, relaying the S3 response back to Central. - It's a bit too complex to do this for my use case (it's not extremely sensitive media uploads), so I just decided to go against best practice and generate access/secret key credentials for an IAM user.
Issue
-
With the above out the way, I have configured an S3 bucket in region
af-south-1
for connecting to Central, with the Central EC2 instance in the same region. -
Upon connection (using the non region specific URL
https://s3.amazonaws.com
as advised in the docs), I get an error:S3Error: The af-south-1 location constraint is incompatible for the region specific endpoint this request was sent to. at parseError (/usr/odk/node_modules/minio/dist/main/internal/xml-parser.js:35:13) at Object.parseResponseError (/usr/odk/node_modules/minio/dist/main/internal/xml-parser.js:82:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Client.makeRequestStreamAsync (/usr/odk/node_modules/minio/dist/main/internal/client.js:476:19) { code: 'IllegalLocationConstraintException', requestid: 'D4MEBFK1GXE8J12Y', hostid: '7AkjYY7VYZH9A2yKAFO6Ne1EL1/AKcU80CL7FGOvReOp+ReDy3AlXRiZs9BCHTQMUjPq0Z0iLOc=', amzRequestid: 'D4MEBFK1GXE8J12Y', amzId2: '7AkjYY7VYZH9A2yKAFO6Ne1EL1/AKcU80CL7FGOvReOp+ReDy3AlXRiZs9BCHTQMUjPq0Z0iLOc=', amzBucketRegion: 'af-south-1' }
-
If I attempt the region specific URL
https://s3.sf-south-1-amazonaws.com
, then I get a different error:S3Error: The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'af-south-1' at parseError (/usr/odk/node_modules/minio/dist/main/internal/xml-parser.js:35:13) at Object.parseResponseError (/usr/odk/node_modules/minio/dist/main/internal/xml-parser.js:82:11) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Client.makeRequestStreamAsync (/usr/odk/node_modules/minio/dist/main/internal/client.js:476:19) at async Client.getBucketRegionAsync (/usr/odk/node_modules/minio/dist/main/internal/client.js:526:19) at async Client.makeRequestStreamAsync (/usr/odk/node_modules/minio/dist/main/internal/client.js:447:25) { code: 'AuthorizationHeaderMalformed', region: 'af-south-1', requestid: '8S4ZCAANYKKKJEVW', hostid: 'tpcMWQj6s0rTzOXt1GifWdGLYp6U/t0GQSak6TU5J890VHXC4weJw5uwQd6t1/9L6CoUJ8YodCw=', amzRequestid: '8S4ZCAANYKKKJEVW', amzId2: 'tpcMWQj6s0rTzOXt1GifWdGLYp6U/t0GQSak6TU5J890VHXC4weJw5uwQd6t1/9L6CoUJ8YodCw=', amzBucketRegion: undefined }node:internal/process/promises:391 triggerUncaughtException(err, true /* fromPromise */);
-
I attempted modifying the code to add the region param
'region': 'sf-south-1'
to no avail.
Question
Is there a config option I am missing to specify the region?
Is disallowing any region other than us-east-1
for AWS expected behaviour?
Offer To Assist
- If other people also face this issue, please comment to let us know!
- If this is a genuine bug, and it would help me debugging further to find the cause, I am more than happy to PR.
- For now, I plan to work around this by simply creating an S3 bucket in
us-east-1
.