.env
file. This is a very good solution for testing or educational environments where you intend to push the app to a remote repository like GitHub, and no front end is involved.
.env
files to store secrets. Before platform and SaaS alternatives made it into the spotlight, developers used a .env
file that is not committed to a public repo to keep all their keys and secrets there.
While the approach is still used today, it is primarily recommended for use in local and development environments only. This is so because exposing your secrets is just one “commit” away from being exposed, and anyone with access to the .env
file basically has all the keys to your kingdom.
Using a .env
file helps you mitigate the risk of exposing your API keys, but you still need to be careful when pushing code to a remote repository. To have peace of mind, make sure to include a .gitignore
file in your local repository. A .gitignore
holds a list of directories and files that you want to “ignore” when pushing code to the version control platform, for example, GitHub.
Use a gitignore generator to make sure you cover all of the files and directories potentially holding sensitive data.
Example of a .gitignore
file:
.env
file. You can also use the dotenv
package to work with .env
files easily.
All you have to do is add a require
reference for its config method as early as possible in your code. Afterward, you can always fetch a particular secret with a process.env
call of the key, whose value you want to get like so.
.env
file and enter your secrets in the appropriate format:
.env
file looks like, how you can create one and import it in your script, as well as use its content anywhere throughout your JavaScript code.
For this particular case, we will use two secret key-value pairs that closely resemble those you would typically find in a real-world Web3 DApp context, even if it is a rather simple one.
First, create a .env
file in your project root and add your “secrets” to it:
.env
and .gitignore
files to protect sensitive data. If you look into the .gitignore
file, you will see a list of files and directories that are not pushed to the remote repository, and you will not find a .env
file committed along with other files. To use this project, you need to create your own .env
file after you clone the repository.
.env
file, for example, as is the case for Vercel and Heroku. Alternatively, you can enter your production secrets within the platforms to give you a sense of security, but once they are pushed to the (public) repo, the keys will be visible to anyone.
index.js
file in the root directory holds the server’s code, and as you can see, is very straightforward:
.env
file of the project or port 3000 if you don’t specify it explicitly. It then creates a route to the index.js
file inside the routes directory, where the URL is built to then send a GET request to the Etherscan API. Here’s the route file:
Access-Control-Allow-Origin
header. Ensure that sensitive information is not exposed by specifying the origin in the Access-Control-Allow-Origin
header. This should be set to a trusted domain rather than using a wildcard (*
) or null
value.Access-Control-Allow-Origin
header should only be sites that are trusted. Avoid reflecting origins from cross-origin requests without proper validation, as this is easily exploitable.Access-Control-Allow-Origin: null
header, as cross-origin resource calls from internal documents and sandboxed requests can specify the null origin. CORS headers should be properly defined in respect of trusted origins for private and public servers.script.js
file in the src
directory.
script.js
file to send the request to that address.
const url = 'http://localhost:4000/balance';
. In this case, the server is running on the same machine, but you’ll have to add the address where you’ll deploy the server in case.
Then we build the POST request’s body. The response is then cleaned up a bit to display only the first six digits.
The same side effects apply to this concept, so implementing a rate limiter and CORS is again a good solution to avoid abuses.
You can find the source code and how to test it in its GitHub repository here.
script.js
file from the example showing how to protect an RPC endpoint, you’ll notice a connection to the back end via a URL like this: http://localhost:4000/YOUR_ROUTE
.
This is because the server was initially tested in a local environment.
To make this work on the internet, follow these steps:
http://localhost:4000/
in the front-end files with the URL of your deployed server..git
and GitHub when handling your DApp secrets. This means you can use it as a private repo for everything you normally store in a .env
file.
Once you have set everything up in the Dotenv Vault interface, you can use the pull function to instantly sync it locally to any device you want via your CLI:
development
to production
environment variables—all you need to do is pull the file for the appropriate environment:
.env
file sync. Once you have the .env
file locally, you will need to build it and then fetch its decryption key. With the key safely in your possession, it can be entered into GitHub Actions ⇒ Secrets, as in this example, or any other CI/CD platform like Heroku, CircleCI, Netlify, and Vercel, among many others.
The same goes for other cloud build platforms like AWS, Google Cloud Platform (GCP), Gatsby, and even those supporting the containerized application process like Docker and Kubernetes. And once you have entered your decryption key in the appropriate platform’s settings, all you need to do is make a require
reference to the [dotenv-vault-core package](https://github.com/dotenv-org/dotenv-vault-core)
as early in your code as possible:
Figure 8: Dotenv Vault integration example -