Using LPM Vault
Store project secrets in LPM Vault and load them into your application with LPM CLI.
LPM Vault is a macOS app for project environment variables. It keeps secret values in the macOS Keychain, outside your project files.
lpm dev and lpm run read those values and pass them to your application at startup.
How it works
The app and LPM CLI share the same local vault under your macOS user account:
LPM Vault → macOS Keychain → LPM CLI → application environment
↑
lpm.json > vaultThe vault field in lpm.json identifies the project's vault. It contains no secret values and grants no access by itself.
Your application reads normal environment variables, such as process.env.DATABASE_URL in Node.js. No application SDK or dotenv export is required.
Local use does not require cloud sync or a Registry account. The app can stay closed while LPM CLI reads saved values from the Keychain.
Quickstart
This workflow requires macOS 14 or later, LPM Vault, and an official signed LPM CLI build.
1. Create an env project
Open LPM Vault and unlock it with Touch ID or your Mac password.
In your personal vault, select New Project. Enter a project name, then select Create project.
If your project already has a vault field in lpm.json, use the matching env project in the app.
2. Add variables
Select the .env environment, then select New key. Add the variables that your application needs, such as DATABASE_URL and API_KEY.
The app calls the default environment .env. This label represents vault storage, not a file in your project.
3. Connect your project
Select the vault ID beside the project name to open Env project configuration. Copy its ID into lpm.json beside package.json:
{
"$schema": "https://cli.lpm.dev/schemas/lpm.json",
"vault": "7f3a1e2c-5b9d-4a8f-b6c1-9b1d2e3f4a5b"
}Replace the example ID with your app's ID. If lpm.json already exists, add the field to its existing contents.
Commit lpm.json with the project. The ID keeps the same vault association after a directory rename or move.
4. Start your application
From the project directory, run:
lpm devThis command starts your configured development server with the vault variables. For another package.json script, use lpm run:
lpm run startTo inspect the default vault without showing values, use lpm env:
lpm env listChoose an environment
Create separate environments in LPM Vault for development and staging. The app shows development as .env.development and staging as .env.staging.
Use the environment name without the .env. prefix:
lpm dev --env=development
lpm run start --env=stagingThese commands can load vault values without matching dotenv files on disk.
Select an environment in lpm.json
Set tasks.<name>.env to choose an environment automatically:
{
"vault": "7f3a1e2c-5b9d-4a8f-b6c1-9b1d2e3f4a5b",
"tasks": {
"dev": { "env": "development" },
"start": { "env": "staging" }
}
}With this configuration, lpm dev selects development, and lpm run start selects staging.
The selection order is:
- The command's
--envvalue. tasks.<name>.envinlpm.json.- The
env.<name>mapping inlpm.json. - The
defaultvault environment.
Override the configured selection for one run:
lpm dev --env=staging
lpm dev --env=defaultChanging the selected environment in the app does not change the CLI selection.
Move from .env files
In LPM Vault, select the destination environment. Use Import .env to import the existing file.
The app replaces matching keys in that environment and preserves its other keys. Import leaves the original file on disk.
For a terminal workflow, use lpm env import:
lpm env import .env
lpm env import .env.staging --env=staging
lpm env list --env=stagingThe CLI preserves existing vault values unless you pass --overwrite:
lpm env import .env.staging --env=staging --overwriteAfter import, make sure that the vault contains the required keys. Remove the secret values from the original files, then restart the application.
Keep only empty placeholders or non-secret examples in .env.example. Keep any plaintext exports outside Git.
Why .env can appear again
If .env is absent and .env.example exists, lpm dev creates .env from that example.
This behavior also applies to projects that use LPM Vault. The copy contains the example's contents, not an export of vault values.
Vault storage keeps your secret values outside project files. It does not disable dotenv loading or the example-file copy.
Runtime behavior
Value precedence
For a selected mode, LPM CLI normally loads .env, .env.local, .env.<mode>, then .env.<mode>.local. Later files override earlier files.
Configured file paths and environment inheritance can change the file selection. Vault values load after those files and override matching keys.
Default-environment fallback
Each vault environment contains an independent set of values.
If the selected environment is missing or empty, runtime loading falls back to the default vault environment.
If the selected environment contains any values, LPM CLI uses that set without merging keys from default.
For example, a non-empty staging environment does not inherit a DATABASE_URL stored only in default.
Changes and app locking
LPM CLI reads vault values before it starts the application. After a value changes, restart the application through LPM CLI.
Locking or closing LPM Vault does not revoke variables already passed to a process. The app's lock protects its interface, while macOS controls Keychain access.
Once injected, the values are normal process environment variables. Your application and its child processes can read them.
Environment checks
An envSchema can require variables before startup. LPM CLI checks the resolved values after it loads the files and vault.
--no-env-check skips the schema check for one run. It does not disable vault loading.
Runtime-hook variables such as NODE_OPTIONS and LD_PRELOAD are filtered from project secrets. See the runtime environment policy.
Troubleshooting
The CLI cannot find my variables
Make sure that lpm.json > vault matches the ID in LPM Vault. Run the command from the connected project directory.
Inspect the intended environment with lpm env list:
lpm env list --env=development
lpm env list --env=stagingUse the same environment name for application startup. A clone on another machine needs its own local secrets or an authorized cloud pull.
The CLI reports a Keychain access error
Use an official signed LPM CLI build. An unsigned development build cannot access the shared macOS Keychain storage.
If macOS reports a locked or unavailable Keychain, unlock it in your macOS login session. Then retry the command.
The application still uses an old value
Make sure that the app and CLI select the same vault and environment. Restart the application through lpm dev or lpm run.
The app's environment selector does not update an existing process.
Optional cloud sync
The app and CLI use the same local values on the same Mac and macOS account. No push or pull is required between them.
Cloud sync stores an encrypted copy on the LPM.dev Registry. See Secrets vault for plans, sharing, and access requirements.
For command examples, see lpm env cloud sync. Runtime startup reads local values and does not automatically pull cloud changes.
See also
lpm dev— start a development serverlpm run— run project scriptslpm env— manage variables from the terminal- Managing secrets — schemas, imports, and environment workflows
- Secrets vault — storage, encryption, and cloud sync
lpm.jsonvault identity — connect a project to its vault