Using Ghost on GitHub. How do I prevent API keys from being exposed? Can I use dotenv?

Hello everyone,

I have been manually having to delete all my API keys from my ghost theme every time I upload it to GitHub which is honestly a pain.

Is there an easier way?

A friend told me about dotenv but that seems to be for server side apps but the JavaScript in ghost themes run on the client.

I think your best bet is to have a config partial which contains all the sensitive data, and you have git ignore that file. If you’re trying to use github actions, you can add a build step which creates the config file programmatically

Thanks for the response!

I don’t fully understand it though, how would I make a config partial? Would I be able to access the variables in my JS files?

So you would include this before your scripts, and it would be something like this:

window.themeConfig = {
    contentAPIKey: 'key',
    // remaining keys go here
1 Like

Wait, so I would put this in a partial and then include it either on default.hbs or the specific page I would need it? And then .gitignore on the partial?

1 Like

Yep, exactly! It’s very similar to how dotenv works, but since Ghost doesn’t support executing arbitrary code, you put that data in a config partial instead

1 Like

Just to go back to the beginning here:

I have been manually having to delete all my API keys from my ghost theme every time I upload it to GitHub which is honestly a pain.

What API keys are you referring to, and why do you have to delete them?

Hi Hannah,
I use three APIs in my ghost theme. The Google Books API, and two for SearchInGhost (which I create in the Ghost Admin Panel).

I have a list of books on my website that I use the books API to fetch info about including book covers, titles, authors and descriptions.

You can see the list of books here.

On the same page you can see two search bars (one for the whole website, one just to search through the books. Each of these uses a different SearchInGhost API key.

I use GitHub to work on my theme, to let me revert back to any point and to collaborate with others and I don’t want the confidential API keys to be exposed there.

This is my theme on GitHub.

Before uploading my theme to github, I used to go in and manually delete the API keys from the Javascript files and then add them back in (because I’d need them for testing and for production).

By putting them in a partial file and adding that file to the .gitignore, I’ve neatly solved this problem!

These are client side API keys though that are readily exposed on your site, so I don’t understand why you’re deleting them.

Doesn’t really matter that they are exposed in GitHub, unless you’re worried about someone forking the theme and not replacing the keys I guess.

Oh! I see now (just viewed the source of my website)

Yeah, you’re right they are already exposed on the site.

There might be little benefit to what I’ve done indeed :sweat_smile:

To be honest I don’t feel like I know what I’m doing and I’m just making it up as I go. When exposing a key in the past, I get emails from various services yelling at me, so I assumed it was serious.

Generally speaking, there are two types of API keys:

First off, you have your traditional secret API keys that have write access to your account or to the API resources, so it can be used to do damage (e.g. change data, delete stuff, or worse). This is the default for most APIs. Never ever use these in client-side code. That’s probably why those emails were yelling at you.

An example of a secret API is the Ghost Admin API. you can use it to edit content, delete posts, and basically destroy the entire site. So don’t publish your Admin API key anywhere, ever.

Then there are read-only API keys that are meant to be used in client-side code. They can only read data from the API, not write to it or change anything. For example the Ghost Content API. These are fine to use in client-side Javascript since people can’t abuse them. Often it is noted explicitly in the documentation if you can use a key in your client-side code.

I haven’t used the Google Books API, but I’ve worked with other Google APIs and most of them are very dynamic and configurable. So if you have set up a read-only API key, it should be fine to just leave that key in your repository if you don’t want to bother with it too much.

1 Like

Thanks for the explanation!

This reassures me.

I believe that it’s a read-only as I only use it for reading and edit the book list manually on Google Books. Same with the SearchInGhost Ghost Content API keys, it just looks at content to use for searching.

I would suggest migrate your repository to Gitlab rather than Github. Why? Because Gitlab offer you free PRIVATE repositories (in github you must pay for private repos), thus you can versionate whatever you want without this issue of privacy.

Github has offered unlimited free private repos for a while :wink:

Sorry, my bad! Actually I made 2 mistakes in the advice: Im bot sure it would be a good practice to store API keys even in a private repo.

If you really really need to fiddle with the admin API key, I collected a couple of tips on how to exclude it from both git and your production build.