envkey-source

envkey-source is a cross-platform CLI tool to load an EnvKey environment for any language, in development or on a server.

If you haven't yet, check out the Integration Quickstart before reading further.

Installation

If you've already installed the EnvKey UI on your machine, envkey-source should have been installed automatically the first time you opened the UI.

envkey-source compiles into a simple static binary with no dependencies, which makes installation a simple matter of fetching the right binary for your platform and putting it in your PATH. An install.sh script is available to simplify this.

Install via bash:

VERSION=$(curl https://envkey-releases.s3.amazonaws.com/latest/envkeysource-version.txt) && curl -s https://envkey-releases.s3.amazonaws.com/envkeysource/release_artifacts/$VERSION/install.sh | bash

Verify and install:

You can verify the install script and envkey-source binaries before running them by installing minisign and running this:

LATEST_VERSION=$(curl https://envkey-releases.s3.amazonaws.com/latest/envkeysource-version.txt) \
&& ARTIFACT_URL=https://envkey-releases.s3.amazonaws.com/envkeysource/release_artifacts/$LATEST_VERSION/install.sh \
&& curl -O $ARTIFACT_URL -O $ARTIFACT_URL.minisig \
&& { minisign -Vm install.sh -P "RWQ5lgVbbidOxaoIEsqZjbI6hHdS5Ri/SrDk9rNFFgiQZ4COuk6Li2HK" || { rm install.sh && install.sh.minisig &&  echo "Error: install.sh signature invalid. Exiting with error." >&2; exit 1; }; } \
&& echo install.sh verified \
&& chmod +x install.sh \
&& ./install.sh \
&& rm install.sh install.sh.minisig

Install manually:

Find the release for your platform and architecture, and stick the appropriate binary somewhere in your PATH (or wherever you like really).

Usage

To execute any shell command directly with your EnvKey environment set:

envkey-source -- any-shell-command

To type less, use the es alias:

es -- any-shell-command

You can reference EnvKey variables in your shell command by wrapping them in single quotes:

es -- ping '$DATABASE_URL'

To automatically re-run the command when the environment changes, use the --watch / -w flag:

es -w -- ./start-server

You can run a different command when the environment changes instead, use the --on-reload / -r flag:

es -r ./reload-env -- ./start-server

Or run a command only when the environment changes (a change hook):

es -r ./on-reload

With either -w or -r, you can reload only when specific variables change:

es -w --only DATABASE_USER,DATABASE_PW -- echo '$DATABASE_USER:$DATABASE_PW' 

With either -w or -r, you can also do a rolling reload to avoid downtime when you have multiple servers/processes connected to a single ENVKEY. Just add the --rolling flag:

es -w --rolling -- ./start-server

By default, this will reload any connected processes in up to four batches, with a 5 second delay between batches. You can use the --rolling-pct flag to change the number of batches, and the --throttle flag to change the delay.

Your EnvKey variables are available to use in shell commands. Just be sure to wrap the variables (or the whole command) in single quotes, otherwise variables will resolve before envkey-source loads your config.

Will work:

es -- echo '$SOME_VAR'
es -- echo '$SOME_VAR' '$ANOTHER_VAR'
es -- echo 'SOME_VAR=$SOME_VAR, ANOTHER_VAR=$ANOTHER_VAR'
es 'echo $SOME_VAR'

Won't work:

es -- echo $SOME_VAR
es "echo $SOME_VAR"

When using the -w or -r flags, you can get the previous value of an EnvKey environment variable after a reload by prefixing it with __PREV_:

es -r 'echo "previous value: $__PREV_SOME_VAR | new value: $SOME_VAR"' -- echo 'initial value: $SOME_VAR'

When using the -w or -r flags, use the --throttle flag to control the maximum rate that restart/reload commands will be dispatched. The default is one per 5 seconds (5000 ms). If your command or reload command takes a long time to initialize, you may want to increase this.

You can set your EnvKey environment in the current shell:

eval "$(es)"

Or output your environment variables to a file:

es --dot-env > .env
es --pam > /etc/environment
es --json > .env.json
es --yaml > .env.yaml

You can automatically set your EnvKey environment whenever you enter an EnvKey-enabled directory. Add the following to your shell config for each shell type.

bash (~/.bashrc or ~/.bash_profile):

eval "$(es --hook bash)"

zsh (~/.zshrc):

eval "$(es --hook zsh)"

Use the --cache / -c flag to maintain an encrypted file-system cache for offline work:

es -c -- any-shell-command

Use the --mem-cache / -m flag to cache the latest values in memory and keep them automatically updated on changes. This avoid the latency of a request to the EnvKey host on each load, but offers less strong consistency guarantees:

es -m -- any-shell-command

Flags

  -c, --cache                   cache encrypted config on disk as a local backup for offline work (default is false)
      --cache-dir string        cache directory (default is $HOME/.envkey/cache)
      --client-name string      Client name for logging when wrapped by another SDK
      --client-version string   Client version for logging when wrapped by another SDK
      --dot-env                 change output to .env format
      --env-file string         Explicitly set path to ENVKEY-containing .env file (optional)
  -f, --force                   overwrite existing environment variables and/or other entries in .env file
  -h, --help                    help for envkey-source
      --hook string             hook for shell config to automatically sync when entering directory
      --ignore-missing          don't output an error if an ENVKEY or .envkey file is missing
      --json                    change output to json format
      --kill                    kills watcher daemon process if it's running
  -m, --mem-cache               keep in-memory cache up-to-date for zero latency (default is false)
  -r, --on-reload string        command to execute when environment is updated (default is none)
      --only strings            with -w or -r, reload only when specific vars change (comma-delimited list)
      --pam                     change output format to be compatible with /etc/environment on Linux
      --retries uint8           number of times to retry requests on failure (default 3)
      --retry-backoff float     retry backoff factor: {retry-backoff} * (2 ^ {retries - 1}) (default 1)
      --rolling                 no-downtime rolling reloads across all connected processes with -w or -r
      --rolling-pct uint8       min % of connected processes to reload in each batch with --rolling (default 25)
      --throttle uint32         min delay between reloads with -w, -r, or --rolling (default 5000)
      --timeout float           timeout in seconds for http requests (default 20)
      --unset                   unset all EnvKey vars in the current shell (example: eval $(envkey-source --unset))
      --verbose                 print verbose output (default is false)
  -v, --version                 prints the version
  -w, --watch                   re-run command whenever environment is updated (default is false)
      --yaml                    change output to yaml format

Shell Injection

When using envkey-source to inject EnvKey environment variables into the shell, all variables are wrapped in single quotes and any single quotes the variables might contain are escaped. This removes any potential for shell injection.

Overriding Vars

By default, envkey-source will not overwrite existing environment variables or additional variables set in a .env file. This can be convenient for customizing environments that otherwise share the same configuration. But if you do want EnvKey vars to take precedence, use the --force / -f flag. You can also use branches for this purpose.

ENVKEY / .env file / .envkey file resolution order and precedence

  1. ENVKEY environment variable has highest precedence.
  2. If ENVKEY environment variable unset, --env-file parameter is checked and takes precedence if so.
  3. If neither ENVKEY environment variable or --env-file is set, the library searches for either a .env(with an ENVKEY set) or a .envkey file (JSON with orgId and appId set), starting in the current directory then checking recursively upwards. The file found at the lowest depth (i.e., closest to the current directory) is chosen. If both files are found at the same depth, the .env file takes precedence.
  4. If an .envkey or .env file with an ENVKEY set in it still hasn't been found, check for.env with ENVKEY present at ~/.env.
  5. If .env without ENVKEY is found, overrides are still applied, unless an existing environment variable is already set, in which case that takes precedence. If an .envkey is found, no further lookup for .env above this location occurs.

x509 error / ca-certificates

On a stripped down OS like Alpine Linux, you may get an x509: certificate signed by unknown authority error when envkey-source attempts to load your config. envkey-source tries to handle this by including its own set of trusted CAs via gocertifi, but if you're getting this error anyway, you can fix it by ensuring that the ca-certificates dependency is installed. On Alpine you'll want to run:

apk add --no-cache ca-certificates