I would like to create an Atlas function to generate AWS CloudFront signed urls using the aws-sdk (v2.1127.0), as written below:
exports = function makeDownloadUrl ({ objectKey, expiresInMinutes }) {
const cloudfrontInfo = context.environment.values.aws.cloudfront
const cloudfrontDistributionDomain = cloudfrontInfo.distributionDomain
const url = `${cloudfrontDistributionDomain}/${objectKey}`
const keyPairId = cloudfrontInfo.keyPairId
const privateKey = context.values.get('cloudfrontPrivateKey').replace(/\\n/g, '\n')
const CloudFront = require('aws-sdk').CloudFront
const signer = new CloudFront.Signer(keyPairId, privateKey)
const expirationEpoch = makeExpirationEpoch(expiresInMinutes)
const options = { url, expires: expirationEpoch }
return signer.getSignedUrl(options)
}
function makeExpirationEpoch (expiresInMinutes) {
const now = new Date()
const millisecondsPerMinute = 60000
const expirationDate = new Date(now.getTime() + expiresInMinutes * millisecondsPerMinute)
return expirationDate.valueOf()
}
However, when running this code, it results in the error: FunctionError: 'crypto' module: error creating sign
I believe the issue occurs when the aws-sdk module calls crypto.createSign. I checked your JavaScript Support Documentation for the crypto module, and it indicates that this method should be supported, but in practice it does not appear to work.
Do you guys support this crypto method? If not, I believe you need to update your documentation accordingly.
If you do support this method, am I doing something else wrong? The code appears to work fine when run on my local computer.
Ah, this takes me back. I ran into almost the exact same issue a while ago, spent way too long assuming I’d messed up smth in the signing logic, only to realize it was crypto.createSign quietly breaking behind the scenes. It’s honestly kind of misleading when the docs say it’s supported, but you hit a wall as soon as you actually try to use it in Atlas functions.
In my case, I ended up switching to pre-signing URLs externally and passing them into the function, which felt like a step backwards but at least worked. Would definitely be nice if the docs were clearer on what’s actually usable in that runtime, feels like trial and error half the time.
Curious if anyone found a proper workaround within Atlas? I’d rather not keep offloading everything to Lambda just for crypto to behave.
Yes I ended up doing the exact same thing–switching to pre-signing URLs externally in Lambda and receiving them back to the Atlas function. There was no other solution I could find to do it all within Atlas.
But now that they’re deprecating almost all of Atlas App Services, this issue doesn’t even matter for us anymore since we had to switch almost our entire app to Lambda anyway haha.