Set passwords: plain, env or bxsecret

On this page

Set passwords: plain, environment variable or bxsecret

The console needs a password. The SMTP and AI settings take secrets too. There are three ways to give BxLens a secret. All three go in boxlang.json, under modules.bxLens.settings.

HowEffortVerdict
1. Plain"password": "my-password"EasiestA bad idea. The secret sits in a file you may commit or back up. Fine for a throwaway demo.
2. Environment variable"password": "${env.BXLENS_PASSWORD}"EasyGreat. Nothing secret in the file, and every container platform and CI knows how to set one.
3. bxsecret:"password": "bxsecret:AbCdEf123...=="More stepsGood. Encrypted in the file, but you must look after the seed.

You can also combine 2 and 3: an environment variable can hold a bxsecret: value (see below).

1. Plain

{ "modules": { "bxLens": { "settings": { "console": { "password": "my-password" } } } } }

It works, and it is the quickest way to try the console. Do not use it on a server people can reach, and never commit it.

2. Environment variable

BoxLang replaces ${...} placeholders in boxlang.json when it loads the file, module settings included. Set the variable on the server, then name it in the file:

{
	"modules": {
		"bxLens": {
			"settings": {
				"console": {
					"password": "${env.BXLENS_PASSWORD}",
					"viewerPassword": "${env.BXLENS_VIEWER_PASSWORD}"
				}
			}
		}
	}
}
export BXLENS_PASSWORD="a long random password"
  • The env. prefix is optional since BoxLang 1.17: ${BXLENS_PASSWORD} works too. If a Java system property has the same name, the property wins.
  • The variable is read at startup. Restart the runtime after you change it.
  • Check that the variable is set. BoxLang leaves a placeholder it cannot resolve as plain text, so with BXLENS_PASSWORD missing the password becomes the literal text ${env.BXLENS_PASSWORD}. Anyone who guesses the variable name can sign in. Test the sign in after a deploy, and leave out viewerPassword entirely if you do not use the viewer role.
  • A default goes after a colon, ${env.NAME:default}, and needs at least one character. Do not use a default for a password.

This is a BoxLang feature, so it works for any setting, see the BoxLang configuration docs. Some BxLens settings also have their own variable setting: ai.apiKeyEnv, the SMTP password in Settings, Notifications, and registration.keyEnv. They take the variable name, not a placeholder.

3. bxsecret

A bxsecret: value is encrypted with the runtime's secret seed. BoxLang decrypts it when it loads the configuration (BoxLang 1.17 or newer). Make one with:

boxlang generatesecret "a long random password"
# bxsecret:AbCdEf123...==

Copy the whole output, prefix included, into the setting. Make a different value for each password.

{
	"modules": {
		"bxLens": {
			"settings": {
				"console": {
					"password": "bxsecret:AbCdEf123...==",
					"viewerPassword": "bxsecret:GhIjKl456...=="
				}
			}
		}
	}
}

The command is the one BoxLang uses for any secret, see boxlang generatesecret in the BoxLang docs.

An environment variable can hold the bxsecret: value, and the placeholder decrypts it: set BXLENS_PASSWORD to the bxsecret: text and keep "password": "${env.BXLENS_PASSWORD}" in the file. That keeps the file free of both the secret and the ciphertext.

Which settings take a secret

SettingWhat it isNotes
console.passwordThe admin passwordRequired. Without it the console shows a setup page (HTTP 503). Plain, ${env.NAME} or bxsecret:.
console.viewerPasswordThe viewer passwordOptional. A second password for the read only role.
notifications.smtp.passwordThe SMTP password for alerts and reportsboxlang.json only. Or name an environment variable in Settings, Notifications.
ai.apiKeyThe API key of a hosted modelboxlang.json only, the console can never change it. Or use ai.apiKeyEnv with the name of an environment variable. Leave it empty for a local model.

The console never shows these values. The Settings page shows only set or not set.

The seed (bxsecret only)

A bxsecret: value is encrypted with the secret seed of the runtime that made it. Each BoxLang installation creates its own seed in {boxlang-home}/config/.seed. A value only decrypts with the seed it was made with.

This matters in three cases:

  • Several servers share one config. Give them all the same seed, or each server will fail to decrypt the password and show the setup page. Copy the same .seed file to each server, or set BOXLANG_SECURITY_SECRETSEED on each one.
  • A container or a new machine. The seed is created again, so values made elsewhere stop working. Pin it with the environment variable.
  • A lost seed. The values cannot be recovered. Make them again.
export BOXLANG_SECURITY_SECRETSEED=my-shared-seed-value
boxlang generatesecret "a long random password"

You can also set security.secretSeed in boxlang.json, but that keeps the seed in plain text next to the values it protects. Prefer the environment variable or the .seed file.

Do not commit the .seed file or a plain text password.

When it does not work

  • The console shows the setup page, and the log says console.password is empty or cannot be decrypted. The value was made with another seed, was copied without its prefix or was cut. Make it again on a runtime that uses the server's seed. See Troubleshooting.
  • A password with special characters on the command line. Quote it, and use single quotes in a shell where $ or ! would expand.

See also Running Lens in production and Security.