Config, secrets and environment variables

Each config entry reaches every service of a stagelet as an environment variable. Stagely stores plain values, but for secrets only their names and keys.

Each project has a config in the console, under Config. It holds two kinds of entries. Every service of every stagelet gets each entry as an environment variable. These variables override the values in your Compose files.

Kind You add it in Its value lives in Stagely sees the value?
Value The console Stagely’s config snapshots and deploy bundles Yes
Secret The console names it; the agent host holds the value The agent’s encrypted store No

Plain values

Under Values, click Add value. Enter a name and a value, such as GREETING and Hello. Click Save config.

Compose files can use plain values in most fields, such as image: postgres:${POSTGRES_VERSION}. Some fields that the Compose rules check refuse variables.

Limits: a name is an environment variable name of at most 128 characters. A value is at most 32 KiB. The names and values of all plain values together are at most 256 KiB. A config holds at most 200 entries.

Secrets

A secret has two halves. In the console, you add the reference: the environment variable name and the key of the secret in the agent’s store. On the agent host, you store the value under that key.

Add the reference

Under Secrets, click Add secret. Enter the variable name, such as DATABASE_PASSWORD, and the agent secret key, such as db_password. Click Save config.

Store the value on the agent host

Connect to the agent host with the SSH key that setup created. Then store the value as the agent’s user. read -s keeps the value off the screen and out of the shell history.

ssh -i ~/.stagely/cli/setup/production/operator_ed25519 \
  root@<agent host address>
read -rs value
printf %s "$value" |
  sudo -u stagely-agent stagely-agent secrets set \
    -data-dir /var/lib/stagely-agent db_password

List and delete secrets the same way:

sudo -u stagely-agent stagely-agent secrets list \
  -data-dir /var/lib/stagely-agent
sudo -u stagely-agent stagely-agent secrets delete \
  -data-dir /var/lib/stagely-agent db_password

Keys are 1 to 128 letters, digits, dots, dashes or underscores.

The store is secrets.json in the agent’s data directory. The agent encrypts it with AES-256-GCM, under the key in secrets.key in the same directory. When you move the agent, keep both files. Without the key file, nobody can read the store. The encryption protects the store file when it leaks alone, such as in a backup of that one file. It does not protect against someone who can read the whole data directory.

The agent can also read secret values from a dotenv file that your pipeline writes. Give the agent the file with its -secrets-file flag. When the store and the file hold the same key, the file wins.

How secrets reach your app

  • A secret reaches containers only as an environment variable. Compose files cannot use secrets as variables.
  • The agent writes the values to the stagelet’s machine in a file that only root can read. The values never enter the deploy bundle that Stagely keeps.
  • Before a log line leaves the agent, the agent replaces each secret value in it with [secret]. The agent does this line by line, so it hides a value with line breaks one line at a time. It does not hide a value, or a line of a value, that is shorter than 4 characters.
  • When a deploy names a secret that the agent does not have, the deploy fails at the Secrets step, before any machine starts. The error names the missing key.

When config changes

Each deploy freezes the config as it was when Stagely queued the deploy. After you change the config, deploy again: push a commit, comment the deploy command, or click Deploy in the console. A reset reapplies the last good deploy’s config, with the agent’s current secret values.

If two people edit the config at the same time, the second save fails. This keeps the first person’s change. Reload the page, then save again.