Environments & Secrets
glubean splits environment data into two files by design: public vars and private secrets.
File model
.env # Public vars — committed to git
.env.secrets # Credentials — gitignored
.env.staging # Staging vars — committed
.env.staging.secrets # Staging credentials — gitignoredAdd *.secrets to .gitignore.
Why two files
.env (vars) | .env.secrets (secrets) | |
|---|---|---|
| API | ctx.vars.require("KEY") | ctx.secrets.require("KEY") |
| Git | Committed — shared baseline | Gitignored — never in repo |
| Cloud upload | Visible in dashboard | Registered for redaction by built-in rules |
The SDK APIs are separate. vars resolves public variables and secrets
resolves credentials. Keep credentials in .env.secrets so they stay
gitignored and are treated as sensitive inputs during redaction.
Reading values in tests
const baseUrl = ctx.vars.require("BASE_URL"); // from .env
const token = ctx.secrets.require("API_TOKEN"); // from .env.secretsTemplate resolution in configure()
{{KEY}} in configure() searches secrets first, then vars:
export const { http: api } = configure({
http: {
prefixUrl: "{{BASE_URL}}",
headers: {
Authorization: "Bearer {{API_TOKEN}}",
},
},
});That template fallback is convenient for shared HTTP options, but it is not a
reason to put credentials in .env. .env is public project config.
Lookup order
Each key resolves file-first, then falls back to the system environment:
ctx.vars.*("KEY")—.envfile, thenprocess.env.KEYctx.secrets.*("KEY")—.env.secretsfile, thenprocess.env.KEY
If your shell variable names differ from test names, map them with ${...}:
# .env
BASE_URL=${GLUBEAN_URL}
# .env.secrets
API_KEY=${GLUBEAN_API_KEY}Switching environments
glubean run # Uses .env (default)
glubean run --env-file .env.staging # Uses .env.staging + .env.staging.secrets
glubean run --env-file .env.prod # Uses .env.prod + .env.prod.secretsThe CLI automatically pairs each env file with its matching .secrets file.
Next
Last updated on