mehendocs

GuidesProject variables with mehen run

Project variables with mehen run#

How do I give a coding project its variables without a .env?

On this page

A repo that uses the vault commits a mehen.toml at its root, with variable names and no values (mehen.toml). mehen run gives a command those variables, as placeholders, plain values or, only where a human allowed it, real values. Never write a secret to disk: no .env with values, no config file, no shell history.

Set one up#

mehen init --env dev --env staging

mehen init at the repo root creates the project in the vault, bound to the repo's origin remote, and writes mehen.toml with the project id, workspace and vault. It needs a member's machine (not a guest's or a team's) whose scope covers every project. If this machine is refused (forbidden), stop and ask the human or the project's maintainer for a checkout with the existing project's committed manifest; do not bypass the refusal or invent a project id. Once that manifest exists, mehen workspace bind fills in workspace and vault; it never guesses a project from the path.

mehen init writes the [vars] entries as commented examples: declare the real variables before mehen env check or mehen run. --slug names the project (otherwise the repo name), and each --env adds an environment, the first being the default (otherwise just dev). prod and production are always protected and can never be the default.

Then point each "vault" variable at a credential the project may share (one whose home is this project or the workspace; a private one is refused), once per environment:

mehen request api-key --name openai-evals --provider openai --home project --project prj_3kQ9vXyZ7 --reason "run the evals for this project"
mehen wait <intake_id>
mehen env set OPENAI_API_KEY --env dev --item openai-evals
mehen env set LOG_FORMAT --env dev --plain json

Relay the request's ask before you wait. --field picks a field when the item's kind has no single primary field. --plain refuses a value that looks like a secret. Setting a variable needs edit on the project and an unprotected environment; a private credential can never back a shared variable (the human can use a personal override instead, on the project page), and a workspace credential in an environment shared with a guest or a team's machine needs an owner or admin in the browser.

Run#

In any clone or worktree, including a throwaway one under /tmp:

mehen env check                 # does every declared variable resolve for this environment?
mehen run -- bun dev            # run with the project's variables
mehen run --env staging -- bun test

MCP: vault_env for ls and check. There is no MCP tool for mehen run, mehen env set or mehen init.

What happens:

Placeholders need the program to use HTTPS_PROXY and trust the run's CA, which mehen run sets. Bun, Node, curl and most Python and Ruby clients do. A program that ignores them sends the placeholder straight to the upstream, which rejects it as a bad key: the call fails, and the real key was never on the machine.

Do not print the environment (env, printenv, environment dumps) inside mehen run to "debug". Placeholders are useless to you and real values are exactly what must not reach your context. Use mehen env check and mehen show.

Environments and production#

mehen env set works only in unprotected environments, and never points a variable at a credential that backs a protected environment. Only a human, with a passkey, sets protected variables, protection and fences.

A protected environment such as prod runs only when you type --env prod literally on the command line, the machine is allowed protected environments, its owner holds the protected right on the project, and a human approves the run (When a request needs approval). Never set MEHEN_ENV=prod, never try to make a protected environment the default, and never pick an environment from a branch name.

Protected credentials only reach approved protected runs. Wherever else one is named (a dev variable, mehen fetch without a context), the vault holds it back: in a dev run the variable is missing, and mehen fetch needs --project <prj_id> --env <name> naming the protected environment that references it, plus an approval of that exact request.