LPM CLI

Local secrets

Store project secrets outside your repository and load them into applications with LPM CLI.

Local secrets keep project values in protected storage outside your repository. lpm env manages them without an account or application SDK.

lpm dev and lpm run load the values before they start your application. The application reads normal environment variables, such as process.env.API_TOKEN in Node.js.

Quickstart

From the project directory, or any directory below it, store a value and start an existing script:

lpm env set API_TOKEN=example-token
lpm env list
lpm run start

The first write adds a vault ID to the project's lpm.json. list masks values by default. These commands need no desktop app, plaintext export, or cloud connection.

Project identity and configuration

The generated vault field associates the project with its local secrets:

lpm.json
{
  "$schema": "https://cli.lpm.dev/schemas/lpm.json",
  "vault": "7f3a1e2c-5b9d-4a8f-b6c1-9b1d2e3f4a5b",
  "tasks": {
    "dev": { "env": "development" },
    "start": { "env": "staging" }
  },
  "envSchema": {
    "vars": {
      "API_TOKEN": { "required": true, "secret": true },
      "PORT": { "default": "3000", "format": "port" }
    }
  }
}

Keep the generated ID when you add configuration. Do not replace it with this example ID. Commit lpm.json with the project. The ID contains no secrets and grants no access by itself. A directory rename or move keeps the same association.

A clone on another machine has the same ID but needs its own local values or an authorized cloud pull. Deleting the field creates a new association on the next write. It does not delete or recover the old secrets.

CLI approval on macOS

In LPM Vault, select a project and use CLI approval beside All variables. The sidebar icon shows each project's setting without selecting it.

CLI approvalSidebar iconCLI behavior
OffFolderInjects local env values automatically.
OnLockRequires Touch ID or your Mac login password before releasing env values.

Locking the app preserves each project's setting.

Approval applies to every environment in the project on this Mac. Other projects keep their own settings. The CLI still requires approval when the app is closed or locked. If you cancel authentication or it fails, the command stops before running lifecycle hooks or the main script. --no-env-check skips value checks and defaults. Invalid declarations and access approval still stop the command.

Select an environment

lpm env set --env=development API_TOKEN=development-token
lpm env set --env=staging API_TOKEN=staging-token
lpm env list --env=staging
lpm dev
lpm run start
lpm run start --env=development

For each script, selection uses this order:

  1. The command's --env value.
  2. tasks.<name>.env in lpm.json.
  3. The matching env.<name> mapping in lpm.json.
  4. The default environment.

The example configuration selects development for dev and staging for start. Explicit --env=development overrides that selection for one run. --env=default selects the default stored values. Named values do not require matching dotenv files.

Each stored environment is independent. If a selected environment is missing or empty, runtime loading falls back to the default stored environment. A nonempty named environment does not inherit missing keys from the default environment. Explicit lpm env get and list inspect the selected environment without this fallback.

Files, stored values, and validation

The standard dotenv order is .env, .env.local, .env.<name>, then .env.<name>.local. Later files override earlier files. Configured paths and environment inheritance can change that file selection.

Inherited process values take precedence over dotenv values. Stored secrets load after files and can override inherited process values. Schema defaults fill missing values. An invalid required value stops startup. Runtime hooks such as NODE_OPTIONS and LD_PRELOAD are excluded from project values and inherited script environments. Project values also cannot set PATH, HOME, or LPM_HOME.

Inspect the resolved project values with lpm env print:

lpm env print --env=staging --format=json
lpm env check --json

print includes plaintext secrets. secret: true masks diagnostics, not this explicit export. For one run, --no-env-check skips value checks and defaults. It still loads local secrets and rejects invalid declarations.

Import existing dotenv files

lpm env import .env
lpm env import --env=staging .env.staging
lpm env list --env=staging
lpm env import --env=staging .env.staging --overwrite

Import preserves existing destination values unless you pass --overwrite. It stores each value as given. If a value holds hidden characters, such as a no-break space at the end, the import warns. The input file remains on disk. If Git doesn't already ignore it, the CLI adds an anchored rule for its path to .gitignore. If Git already tracks the file, the CLI warns. Untrack it with the git rm --cached command in the warning before you commit. After you check the imported keys, remove secret values from the original file and restart the application. Keep placeholders or non-secret examples in .env.example.

If .env is absent and .env.example exists, lpm dev copies the example to .env. This copy contains example values. It does not export local secrets. LPM CLI writes the copy owner-only and adds a .gitignore rule for it when Git doesn't already ignore it. A rule it can't add is a warning.

Storage and recovery

PlatformLocal storage
macOSData Protection Keychain through an official signed CLI build.
Linux and WindowsEncrypted files in vaults/ in the LPM home. The encryption key uses native secure storage when available.

The LPM home is ~/.lpm, or the directory that LPM_HOME names. In a Git repository that the LPM home can't be kept out of, LPM CLI refuses to write local secrets there; see the LPM home. A home other than ~/.lpm keeps its own OS credential store entries, so it has its own local secrets. Values stored with one home are not visible with another.

On Linux, native key storage uses Secret Service. On Windows, it uses Credential Manager. An unavailable native backend can use an existing file key at .vault-fallback-key in the LPM home. If native storage reports no key and cannot save a new one, initial storage can create a fallback file key. Existing encrypted data still requires its original key.

Encrypted files need their matching encryption key. Copying encrypted files alone does not recover the values on another machine. A missing or conflicting key produces an error. The CLI preserves existing data instead of silently replacing the key.

ProblemRecovery
Values are absent.Check the project directory, vault ID, LPM_HOME, and selected environment with lpm env list --env=<name>.
macOS denies access.Use an official signed CLI build and unlock the Keychain in your login session.
Native key storage is unavailable.Restore access to Secret Service or Credential Manager, or restore the matching fallback key.
The fallback key is lost.Restore the matching key from a trusted backup. An encrypted local file alone is insufficient.
A clone has no local values.Import values or pull an authorized cloud copy before startup.

Do not delete storage files or change the project ID to repair a missing encryption key. For encrypted backup and access details, see environment encryption and access.

Changes take effect at startup

After you change a secret, restart the application through lpm dev or lpm run. An existing process retains the values that it received at startup. The application and its child processes can read those variables.

Optional cloud sync

lpm env push --yes
lpm env pull --yes
lpm env pull --org=acme

Cloud sync requires an eligible LPM.dev Registry plan and authorized keys. Uploads preserve named empty environments, including projects with no keys. A pull replaces local values with the remote payload. Export local values that you need to preserve before a pull. Runtime startup reads local values. It does not automatically pull cloud changes. Each checkout keeps its sync state in .lpm/env-sync.json, which Git never sees. See lpm env cloud sync for personal sync, organization sharing, pairing, and CI access.

See also