I am working on a Gatsby app that implements some 3rd party APIs, all requiring personal credentials. Later on I'm planning to also add a DB, so that will require credentials as well. Since all my code is committed to GitHub, I'm looking for a way to store and access these in a secure way.
While I haven't deployed my app yet, the solution should apply to both local development as well as production.
I'd like to mention that I've never (had the chance to) worked with similar problems in that past, thus I don't even know where to look or what I'm supposed to look for to solve this.
It's important to distinguish between two types of secrets in Gatsby: build-time and runtime.
You can store build-time secrets as environment variables (Gatsby docs).
In a nutshell, you'll create a .env.development
file with your dev environment variables, and a .env.production
file for your prod environment.
Then, at the beginning of your gatsby-config.js
, you'll add this: (no need to install dotenv
, it's already a Gatsby dependency)
require("dotenv").config({
path: `.env.${process.env.NODE_ENV}`,
})
Also make sure that your .env
files are in your .gitignore
to avoid committing them to source control:
# ignore env variables files
.env*
As a last step, you'll need to manually add the variables to every service you're using that needs to build your site. Typically this is going to be your host (Netlify for example), and your CI (GitHub Actions for example).
The strength of Gatsby is fetching data at build time and generating static content. If you can pull your content at build time using a Gatsby source plugin, you should favor this over fetching content at runtime. (See the Gatsby docs on Build-time vs Runtime Data Fetching for more details.)
However, in some cases, you can't fetch data at build time, for example when fetching dynamic content or rendering a Mapbox map.
In this case, saving your secrets as environment variables won't be enough, because the secrets will still be exposed in network calls.
You have several alternative options, for example:
Runtime secrets in Gatsby are obviously more complex to deal with than build-time secrets. If your application relies heavily on runtime data fetching, you could also think about replacing Gatsby with Next.js, which nicely supports runtime secrets through API routes (essentially serverless functions bundled in the framework).
Thanks to HaberdashPI and JakobAttk for their feedback that improved this answer!