Per-Environment Scoping

A single project vault can hold multiple independent environmentsdefault, staging, production, or anything you name. Each environment has its own set of values for the same keys. DATABASE_URL in staging and DATABASE_URL in production are completely separate entries; touching one doesn't affect the other.

Setting and reading per-environment

lpm env set --env=staging    DATABASE_URL=postgres://staging.db/app
lpm env set --env=production DATABASE_URL=postgres://prod.db/app

lpm env list --env=staging
lpm env list --env=production
lpm env get  --env=production DATABASE_URL --reveal

Without --env, operations target the default environment. Inside the local vault the data is stored as { environment_name: { key: value } } — one keychain item per project, structured per-environment.

Listing environments

lpm env ls                                 # overview: name, key count, last modified

Copying between environments

lpm env copy default staging               # whole-environment copy
lpm env copy staging production            # promote staging values to production
lpm env copy default qa --prefix STAGING_  # rewrite keys during copy

Copy targets the destination environment idempotently — keys that already exist on the destination are overwritten. To dry-run a copy, run lpm env diff <src> <dst> first.

Diffing

lpm env diff staging                       # compare local staging vs remote staging
lpm env diff staging production            # compare two local environments
lpm env diff                               # default env, local vs remote (Pro/Org)

The diff is structural — added keys, removed keys, changed values — values themselves stay masked unless you pass --reveal.

Running scripts in a specific environment

lpm run and lpm dev inject the resolved environment automatically:

lpm run dev --env=staging                  # node runs with staging vars
lpm run build --env=production
lpm dev --env=production

The --env flag overrides any LPM_ENV set in the shell. Without --env, the runner falls back to LPM_ENV, then to default.

Schema applies per-environment

The envSchema in lpm.json validates each environment independently:

lpm env check                              # validates default
lpm env check --env=staging                # validates staging
lpm env check --env=production

Required keys must exist in every environment that gets pushed or executed. lpm env example --env=production generates a .env.example from the schema scoped to that environment.

How environments interact with cloud sync

Cloud sync (push / pull) operates on the whole vault, not a single environment. All your environments travel together in one encrypted blob. The dashboard and CLI then filter by name when displaying — no extra round-trip per environment.

OIDC policies in CI are scoped per environment, however: a policy can allow production pulls and deny staging pulls, even though both ship in the same blob. See OIDC for CI for the policy form.

Conventions worth adopting

  • Reserve default for local development; never push secrets a teammate wouldn't have on their machine.
  • Name environments after deployment targets (staging, production, preview), not branches.
  • Treat the schema as the contract: when adding a new required key, set it in every environment before the next push.

Next