Hello 
Itβs quite simple tbh, I just created a smart action and this is the implementation 
// Upload image to gcs
router.post('/actions/items/upload-image', permissionMiddlewareCreator.smartAction(), (req, res) => {
const attrs = req.body.data.attributes;
const attrsValues = attrs.values;
const image = attrsValues['Image'];
const recordGetter = new RecordGetter(items);
recordGetter.get(attrs.ids[0])
.then((item: IItem) => {
// removing some data that bother me :)
// let ext = getExtensionFromHeaders(image)
// if (ext === Extension.Undefined) {
// throwException("No extension could be determined for the given image.")
// }
// let fileContent = removeHeaderFromFile(image)
backofficeAPI.uploadImage(fileContent, item._id, ext, [new ImageSize(1920, 1080), /* ... */)
.then((result: UploadAndResizeImageResponseBody) => {
items
.updateMany({'_id': item["_id"]}, {
'$set': {
'image_url': result.PublicURL,
'updated_at': getCurrentTimestampInSeconds()
}
})
.then(() => {
res.send({success: 'Image uploaded.'});
}).catch(error => {
throwException("an error happened when updating an item: ", error)
});
})
.catch(error => {
throwException("an error happened when using the backoffice: ", error)
});
})
});
// Backoffice API client
class BackofficeAPI {
/* ... */
constructor(/* ... */) {
/* ... */
}
/* ... */
async uploadImage(inputFile: string, id: string, extension: Extension, endSizes: ImageSize[]): Promise<UploadAndResizeImageResponseBody> {
let body = new UploadAndResizeImageRequestBody();
body.ImageSourceB64 = inputFile;
body.ID = id;
body.Extension = extensionToStr(extension);
body.EndSizes = endSizes;
return this.makeAPICall("post", endpointToStr(BackOfficeEndpoints.UploadAndResizeImage), body)
.then(response => {
let responseBody = null
if (response.status != 200) {
responseBody = response.data as EndpointError;
throwException("Error [" + response.status + "]: " + responseBody.Error);
} else {
responseBody = response.data as UploadAndResizeImageResponseBody;
return responseBody;
}
}, reasonOnReject => {
throwException("app call rejected: ", reasonOnReject);
})
.catch(reason => {
throwException("ann error happened when making an http api call: " + reason);
});
}
/////////////////
//////UTILS//////
/////////////////
private async makeAPICall(method: Method, endpoint: string, body: any): Promise<any> {
let timeout = 1000 * this.DefaultTimeout; // Default timeout being in seconds
logInfo("method: ", method)
logInfo("endpoint: ", endpoint)
logInfo("body: ", body)
return new Promise((resolve, reject) => {
axios({
method: method,
url: this.BackOfficeAPIHost + "/" + endpoint,
timeout: timeout, // Wait for 5 seconds
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'x-api-key': this.BackOfficeAPIKey
},
data: body
}).then(
response => resolve(response),
err => reject(err))
})
}
}
export const backofficeAPI = new BackofficeAPI(/* ... */);
throwException(β¦) is just a simple function which logs and throw new Error on demand 
As you can see, I am not setting any CORS at all from the code, but only from the env file:
CORS_ORIGINS=plop_example
It doesnβt change anything if i put a real value or a wrong one:
CORS_ORIGINS=http://my-website.com
CORS_ORIGINS=https://my-website.com
CORS_ORIGINS=http://localhost:3310
CORS_ORIGINS=localhost:3310
...
I hope we can find a solution 
Thanks
Max