0

Problem: Netlify serverless functions run on AWS Lambda. So AWS_ is a reserved prefix in Netlify, meaning I can't use e.g. AWS_SECRET_ACCESS_KEY for my own environment var that I set in the Netlify admin panel.

But the only way I have been auble to authenticate Nodemailer with AWS SES (the email service) is with @aws/aws-sdk and its defaultProvider function that requires process.env.AWS_SECRET_ACCESS_KEY and process.env.AWS_ACCESS_KEY_ID – spelled exactly like that:

import 'dotenv/config'
import nodemailer from 'nodemailer'
import aws from '@aws-sdk/client-ses'
import { defaultProvider } from '@aws-sdk/credential-provider-node'

const ses = new aws.SES({
  apiVersion: '2019-09-29',
  region: 'eu-west-1',
  defaultProvider,
  rateLimit: 1
})

const sesTransporter = nodemailer.createTransport({ SES: { ses, aws } })

When building the function locally with the Netlify CLI, emails are sent.

It fails with 403 and InvalidClientTokenId: The security token included in the request is invalid in the live Netlify environment.

Netlify doesn't have a solution afaik, but mention in a forum post that custom env variables in AWS is a thing. I haven't been able to find anything in searches (they didn't provide any links). The AWS docs are pretty unhelpful as always :/

So the question is, how can this be done?

I thought I was clever when I tried the following, but setting the vars just before creating the SES Transport apparently doesn't help:

  // Trick Netlify reserved env vars:

  process.env.AWS_ACCESS_KEY_ID = process.env.ACCESS_KEY_ID
  process.env.AWS_SECRET_ACCESS_KEY = process.env.SECRET_KEY

  console.log('AWS access key id ', process.env.AWS_ACCESS_KEY_ID) // Logs the correct key!
  console.log('AWS sec key ', process.env.AWS_SECRET_ACCESS_KEY ) // Logs the correct
anatolhiman
  • 1,762
  • 2
  • 14
  • 23
  • 1
    In [previous versions of the NodeJS AWS SDK](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/loading-node-credentials-json-file.html) you could do something like `ses = new aws.SES({accessKeyId: process.env.ACCESS_KEY_ID, secretAccessKey: process.env.SECRET_KEY});` This option is completely missing from the version 3 SDK documentation as far as I can tell. I would suggest trying that though, they may have just removed it from the documentation to discourage people that were using hard-coded credentials inside client-side JavaScript. – Mark B Mar 22 '22 at 12:56
  • Thank you, @MarkB that would make complete sense. But it fails in the same way as before. I'm wondering if there could be more to it, like a geographical region mismatch (me in Europe, Netlify CDN in some other location, AWS region set to EU-west). I guess I won't find out until I hardcode the credentials into my script ... – anatolhiman Mar 22 '22 at 13:14
  • 1
    Regions being different shouldn't matter at all. It's very common to call SES in a different region because it's only available in a few regions. – Mark B Mar 22 '22 at 13:36
  • How do you plan to hard-code the credentials into your script? If you know how to do that, then specifying them as custom environment variables should be trivial. – Mark B Mar 22 '22 at 13:38
  • Yes, you're right, it wouldn't make any difference from using my custom named env vars. – anatolhiman Mar 22 '22 at 14:22

0 Answers0