How To Use Environment Variables and "Secrets"
Environment variables are exactly what they sound like: variables that are set per environment. They are typically used for things like credentials or domains that may change from local to staging to production environments. In PageBuilder Engine, decrypted environment variables are expected to be stored in a .env
file for the local environment and in the root of your repo. Encrypted environment variables should be located in /environment/localhost.(js|json|ts|yaml|yml)
file for local development, and in the other corresponding environment files in the /environment/
directory for other environments.
Environment File Formats
PageBuilder Engine supports both .env
and json
formats for defining environment variable files. Which format you choose depends on personal preference, but ultimately both boil down to a list of key-value pairs.
.env Format
[KEY1]=[VALUE1][KEY2]=[VALUE2]...
.js, .json Format
{ [key1]: [value1], [key2]: [value2], ...}
As mentioned previously, PageBuilder Engine allows you to set environment variables differently depending on what environment you’re in.
Local environment variables
In local development, you can define whatever environment variables you want in the .env
file in the root of your repository. These will override environment variables of the same name defined in the /environment/
directory. However, these variables defined in the .env file are not eligible and are ignored on non-local environments. Therefore, variables defined in your .env
file don’t need to be encrypted since that file is in your .gitignore
file and therefore they only exist on your local system. So in general, use .env
for environment variables defined on your local.
In staging and/or production environments you’ll define environment variables in the /environment/
directory. This provides the advantage of keeping them in the repository so you don’t need to configure environment variables separately on the server - however, this presents its own problem as many of these variables should be secret and not stored in plaintext in the repository. To alleviate this concern, PageBuilder Engine has the ability to decrypt secret variables at “deploy” time when provided the correct key.
Creating and using environment variables
Let’s see how we can actually use environment variables in the sample PageBuilder Engine app we’ve been building.
So far, the only environment variable we’ve used was the OMDB_API_KEY
in our movie-find
content source, so let’s define that one. The first thing we’ll do is go to our .env
file and add it there:
.env
FUSION_RELEASE=latestOMDB_API_KEY=a1b2c3d4e5
The FUSION_RELEASE
value above is a special environment variable. If you don’t know what to put here, you should set it to latest
. For more information, see Environment variables.
The OMDB_API_KEY
value used above is fake - you’ll need to get your own from the OMDb API and use that instead.
We now have everything we need for our content source to work locally.
To get it working in staging/production environments, we’ll need to first encrypt our secret variable, then create an index.js
file in our /environment/
directory.
There are a few different formats you can use for naming the environment variables file. You can define it as a top level file called /environment.js
or /environment.json
, or alternatively in the /environment/
directory as /environment/index.js
or /environment/index.json
. Just make sure you only have one of these.
Encrypting your secrets
To enable secret encryption for your Arc environment, PageBuilder’s deployment tool Maestro comes with a simple application to encrypt and decrypt secrets based on your environment. Because the encryption values are based on a shared key that is provisioned per environment, and because Maestro has access to that key, Maestro is able to securely and statelessly encrypt and decrypt secrets for us - and this makes it the perfect tool for getting our PageBuilder Engine application secrets ready for external environments.
To use the tool, simply go to your environment’s Maestro “Secrets” Page. Copy the “secret” value for our OMDB_API_KEY
and paste it into the “encrypt” text input at the top of the page, then click the “encrypt” button. You should get an encrypted value that looks similar to this:
AQECAHhPwAyPK3nfERyAvmyWOWx9c41uht+ei4Zlv4NgrlmypwAAAMYwgcMGCSqGSIb3DQEHBqCBtTCBsgIBADCBrAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxwBJdfzqcQUpox1xsCARCAf2aXwBJ3pBUP12HWB3cdBboV1/qN0HFEsjNycADYIq7XSANeDYOlu2/Dwt/52R16hK4dbVOt0ofNKKx0b3vtZRaH9bX1Dkx6TDhmo5g32H0aWpiUW6PQIp72/g2CW1nr26T0zxmkxmX9u8ufoQGBXRd1pOfT2EliUhMKabNeSyk=
This encrypted value is now safe to be stored in our git repository and added to our /environment/index.js
file inside of “percent bracket” control characters, like so:
/environment/index.js
export default { OMDB_API_KEY: "%{AQECAHhPwAyPK3nfERyAvmyWOWx9c41uht+ei4Zlv4NgrlmypwAAAMYwgcMGCSqGSIb3DQEHBqCBtTCBsgIBADCBrAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAxwBJdfzqcQUpox1xsCARCAf2aXwBJ3pBUP12HWB3cdBboV1/qN0HFEsjNycADYIq7XSANeDYOlu2/Dwt/52R16hK4dbVOt0ofNKKx0b3vtZRaH9bX1Dkx6TDhmo5g32H0aWpiUW6PQIp72/g2CW1nr26T0zxmkxmX9u8ufoQGBXRd1pOfT2EliUhMKabNeSyk=}"}
Since this KMS key is assigned on a per-client, per-region basis, PageBuilder Engine will automatically decrypt this variable at deploy time so it can be used reliably across different environments (Sandbox, Production, etc.) as long as they are in the same region. And while our app would work locally without the value stored in our /environment/index.js
file (since its decrypted counterpart is already in our .env
file), adding it now means we won’t have to do it later when we deploy our application.
Restrictions
Encrypted environment values will only be accessible during server execution, not in the client, as they will be exposed to users. To ensure this, fusion:environment
will remove all encrypted values in the client. Unencrypted values will be available and should not contain sensitive information.
Now that we have our content source and credentials set up, we can use them to retrieve and display some content.
If you would like to work with private NPM repositories, read Using private NMP respositories in your bundle.