By Coogan Brennan and Thomas Hay
A few times a year, a story makes the rounds of an unfortunate Ethereum developer who, while building a blockchain project, accidentally uploads their super-secret mnemonic phrase—used to generate their wallet—to their public GitHub page. Within seconds, their wallet has been “hacked” and drained of its funds.
Nothing has really been hacked, though: The transaction transferring all assets to the “hacker” address is perfectly sound. That’s why the network processes and accepts it. The network doesn’t care who signs the transaction or what their intent was, just that its cryptography is sound. The network makes the assumption that anyone in possession of a mnemonic, or the generated private keys, is the rightful owner of the assets in the corresponding accounts.
That is cold comfort to the person who has lost control of their wallet. The immediate reaction is to think their wallet has been hacked. It’s understandable! But, before getting to the point where you have to wonder whether your wallet was compromised, it’s good to check you aren’t about to unwittingly expose your private information.
Here are some definitive steps to avoid falling into a similar situation. (Bonus points: the techniques described in this article are great security hygiene for any project, blockchain or not!)
Below, we outline two approaches on how to NOT publish secrets (API keys, private keys, seed phrases, database passwords) to your GitHub repository:
Approach 1: Using .gitignore, a .env file, and dotenv (assumes we are developing using patterns common to Solidity and a workflow using Truffle and MetaMask, even though this has been generalized)
Step 1: Read the documentation on .gitignore. Seriously, read the whole page of documentation.
A .gitignore file allows you to specify files that should not be tracked. You will create a .gitignore file within the directory you are developing your project in. Within that file, you will specify the files that you do not want to track. The documentation will explain to you the various text patterns you can use in order to not track (or track) files.
Here is an example of one:
In line 20, we have added a .env file
Step 2: Set up a .env file to store your environment variables
Environment variables, originally implemented in Version 7 Unix (released in 1979 by Bell Labs, click here for a copy of the manual) change the process(es) that a computing system runs. Environment variables have been implemented in all of the operating systems that our students use to build dApps on Ethereum (Unix, Linux, MacOS, Windows). In this case, your secrets are treated as environment variables, and placed in a file called .env.
Here is an example of a .env file
Step 3: Read the documentation about dotenv. Install dotenv.
Dotenv “is a zero-dependency module that loads environment variables from a .env file into process.env.” (retrieved from https://www.npmjs.com/package/dotenv on September 25, 2020)
nstall dotenv using
npm install dotenv
Add require('dotenv').config() to the start of your application. Utilize
process.env in this file.
Code Example: application.js
//This is the top of application.jsrequire('dotenv').config()//This is an example of process.env later in the filevar PrivateKey = new Buffer(process.env.["PRIVATE_KEY"], "hex"))//Here is another example of using process.envconst APIKey = process.env.API_KEY;
Step 5: Now, if you want to publish to an existing GitHub repository or push to a new GitHub repository, you can do so. Your secrets will not appear be part of your GitHub repository.
Video Tutorial from another source: Daniel Schiffman of The Coding Train provides a video tutorial using a weather application in his video 3.4 Hiding API Keys with Environment Variables (dotenv) and Pushing Code to GitHub.
Text Tutorial from another source: Mason’s Blog has a tutorial called How to Deploy an ERC20 Token in 20 Minutes. It describes how to use a .env file and dotenv in the context of deploying a smart contract using Truffle and Infura.
Approach 2: Using Encrypted Secrets in GitHub Actions (appropriate for those with familiarity with GitHub at an organization level, with the necessary permissions and GitHub account to be able to put these into practice).
Approach 2 uses tooling specifically created by GitHub to solve the issue of secrets being a necessary part of deploying code, but not something that should be revealed to individuals who should not have access to them. This approach is most relevant to an organization or individual using GitHub
Step 1: Read the documentation on Encrypted Secrets. Seriously, read the documentation.
Encrypted Secrets allow you to store and use secrets in a single GitHub repository or across many GitHub repositories. Read the documentation about how to use these, as GitHub does an excellent job of explaining how to use Encrypted Secrets within GitHub Actions
Step 2: Do what the documentation tells you to do. It is pretty good documentation.
You now know two approaches to prevent your secrets from being published to GitHub. Are there other approaches to do this? Certainly. Here are two methods that work for us. The main point we are trying to convey is to make sure you are thinking about where your secrets may show up, and ensuring you take steps to protect yourself. Stay safe out there.