LPM CLI

lpm setup

Configure .npmrc authentication or print GitHub Actions and GitLab CI workflows.

Use lpm setup to configure registry access or create a starting workflow for CI secrets.

lpm setup ci [TARGET] [--env <ENV>] [--registry <REGISTRY>] [--oidc]
lpm setup local [--days <DAYS>]

The ci command requires a target: npmrc, github-actions, or gitlab.

Quickstart

For local npm-compatible clients, create a project token:

lpm login
lpm setup local --days 7
npm install

Commands

CommandResultUse it when
lpm setup ci npmrcWrites a project .npmrc with a literal tokennpm, pnpm, Yarn, or another npm-compatible client runs in CI
lpm setup localWrites a project .npmrc with a new read-only tokenAn npm-compatible client needs local access to private @lpm.dev/* packages
lpm setup ci github-actionsPrints an OIDC workflow fragment and an authorization commandGitHub Actions must pull project secrets with lpm env
lpm setup ci gitlabPrints an OIDC job fragment and an authorization commandGitLab.com CI must pull project secrets with lpm env

If CI uses only LPM CLI, set LPM_TOKEN on the package command. LPM CLI does not need a generated .npmrc file.

- name: Install private packages
  run: lpm ci
  env:
    LPM_TOKEN: ${{ secrets.LPM_TOKEN }}

Examples

lpm setup ci npmrc --json                  # configure npm-compatible CI clients
lpm setup local --days 30 --json            # create a local project token
lpm setup ci github-actions --env staging  # print a secrets workflow
lpm setup ci gitlab --env production --json # return the workflow as JSON

Project configuration in lpm.json

The GitHub Actions and GitLab targets prepare OIDC workflows for lpm env pull.

These workflows use the vault field in lpm.json. The generated deploy step runs lpm run deploy. This example defines the script in lpm.json.

lpm.json
{
  "vault": "7f3a1e2c-5b9d-4a8f-b6c1-9b1d2e3f4a5b",
  "tasks": {
    "deploy": { "command": "./deploy.sh" }
  }
}

Create the local secret project before you generate the workflow:

lpm env set API_URL=https://api.example.com --env production
lpm env push
lpm setup ci github-actions --env production

The lpm env commands create the vault field. Commit lpm.json after this field exists.

The GitHub Actions target copies the vault ID into the printed LPM_VAULT_ID value. If the field is missing, it prints <your-vault-id>.

Replace this placeholder before you use the workflow. A malformed lpm.json or invalid vault ID stops generation.

The generated vault value is quoted. A vault ID cannot contain a GitHub expression.

The GitLab job can read the vault ID from the checked-out lpm.json file. The setup command does not change lpm.json.

lpm setup ci npmrc and lpm setup local do not use lpm.json.

Create .npmrc for CI

If an npm-compatible client needs LPM.dev Registry authentication, run this command:

- name: Configure LPM.dev Registry access
  run: lpm setup ci npmrc
  env:
    LPM_TOKEN: ${{ secrets.LPM_TOKEN }}
- run: npm ci

The command writes this scoped block to the .npmrc that installs read: at the workspace root, or else in the nearest directory with a package.json. Without a package.json around it, the command uses the current directory. LPM CLI prints the directory when it isn't the current one.

.npmrc
# LPM Registry (generated by lpm setup ci npmrc)
//lpm.dev/api/registry/:_authToken=<resolved-token>
@lpm.dev:registry=https://lpm.dev/api/registry/
# End LPM Registry

Only @lpm.dev/* packages use this route. Existing default registries and unrelated .npmrc lines stay unchanged.

The command replaces its previous generated block. LPM CLI writes the file owner-only: 0600 on Unix, without access list entries that the directory would pass on on macOS, and a protected access list on Windows.

A tracked or symlinked .npmrc stops setup before token changes. Remove .npmrc from Git tracking before retrying.

Setup also stops when Git reaches a .git file that it can't use, such as one that points to a missing repository. Git can't then tell whether .npmrc is tracked. Repair or remove that .git file before retrying. Inside a repository, setup stops too when Git can't be run; put Git on PATH before retrying. Outside any repository, setup writes the file without Git.

CAUTION: Do not commit this .npmrc file. The file contains a literal bearer token.

Before it writes the token, the command makes sure that Git ignores .npmrc. If Git doesn't already ignore it, LPM CLI adds an anchored rule for that file to the repository's .git/info/exclude. The shared .gitignore stays unchanged, so the work tree stays clean. If the rule can't be added, setup stops before token changes.

Choose the CI credential

Without --oidc, the command uses one of these credentials:

  1. The global --token <TOKEN> flag
  2. LPM_TOKEN
  3. A valid token from lpm login

If no credential is available, the command stops before it changes .npmrc.

LPM CLI refreshes an expired browser session before it writes .npmrc. If the refresh fails, the command stops and keeps .npmrc unchanged.

Use --oidc to require a CI identity exchange, unless setup is completing a pending token retirement:

lpm setup ci npmrc --oidc

GitHub Actions needs permissions: id-token: write. GitLab.com CI needs LPM_OIDC_TOKEN with the https://lpm.dev audience.

An OIDC error stops the command. It does not use LPM_TOKEN or a saved login as a fallback.

Use --registry with another LPM-compatible registry:

lpm setup ci npmrc --registry https://registry.example.com

A stored session must belong to the selected registry. The generated route ends in /api/registry/.

You can supply the service base URL or its /api/registry endpoint. LPM CLI normalizes the endpoint without duplicating the path.

CI JSON output

If automation needs the file path and credential source, use JSON output:

lpm setup ci npmrc --json

The command still writes .npmrc. The JSON response replaces the token with <redacted>.

Create a local project token

If a local npm-compatible client needs a read-only project token, run these commands:

lpm login
lpm setup local
npm install

The LPM.dev Registry requires a valid browser-backed CLI session. The default token lifetime is 30 days.

Set a lifetime from 1 through 90 days:

lpm setup local --days 7
lpm setup local --days 90

The command changes up to two project files:

  • .npmrc receives a scoped, read-only token for @lpm.dev/* packages.
  • .gitignore receives an anchored /.npmrc rule, unless Git already ignores .npmrc. The rest of .gitignore stays unchanged.

Existing .npmrc lines stay unchanged. A custom default registry also stays unchanged.

A tracked or symlinked .npmrc stops setup before token changes. So does a .git file that Git can't use, such as one that points to a missing repository, because Git can't then tell whether .npmrc is tracked, and so does a project inside a repository where Git can't be run. Inside a repository, setup also stops if it can't add the .gitignore rule. If setup fails later, it restores .npmrc and keeps the rule that it added, which only keeps the file out of Git.

CAUTION: The .npmrc file contains a token. Keep the file outside version control.

Run lpm setup local again before the token expires. The command writes a replacement and retires the previous project token.

Token limits:

  • An account holds up to 100 active tokens that it created, project tokens included. At this limit, lpm setup local fails for a new project, or for a project whose token expired, until you revoke a token in Registry token settings. At the limit, you can still replace the token of a project if that token is active.
  • LPM.dev deletes expired and revoked tokens 30 days later.
  • A user creates 10 tokens a minute or fewer, lpm setup local included. Token creation on the dashboard shares this limit. Above it, the command fails with HTTP 429, and it works again when the minute ends.
  • From one IPv4 address or IPv6 /64, lpm setup local creates, replaces, and revokes project tokens 100 times a minute or fewer for each action. Above that, it fails with HTTP 429 before it changes a token.

LPM.dev does not limit how often you revoke tokens in Registry token settings. As a result, no person who holds a token can stop you from revoking it. A revoked token can continue to work for up to a minute, until the caches of the Registry drop it. For each user, the first 20 revocations a minute, across the dashboard, the API, and lpm setup local, also remove the token from the caches at once.

The command writes the .npmrc that installs read: at the workspace root, or else in the nearest directory with a package.json. Without a package.json around it, the command uses the current directory. LPM CLI prints the directory when it isn't the current one.

JSON output reports the paths, scope, expiry, whether .gitignore changed (gitignore_updated), and warnings. It does not include the token.

lpm setup local --json

Print the workflow fragment for the production secret environment:

lpm setup ci github-actions

Select another environment with --env:

lpm setup ci github-actions --env staging

The command prints three items:

  1. A complete GitHub Actions job fragment for lpm env pull --oidc
  2. An lpm env oidc allow command for the repository
  3. An instruction to configure the returned policy ID as LPM_OIDC_POLICY_ID

The command prints output only. It does not create or change a workflow file or authorize the repository.

Run the printed authorization command from a logged-in development machine. Then add the workflow fragment to .github/workflows/deploy.yml.

The authorization command also uploads protected material for the personal env project. Continue only when LPM CLI reports that CI escrow is enabled.

If the escrow upload fails, correct the error and run the same authorization command again. The command updates the matching policy.

When you run the authorization command, LPM CLI gets the immutable repository ID from GitHub. Private repositories need GITHUB_TOKEN, GH_TOKEN, or --repository-id.

The job fragment uses ubuntu-latest and includes all required job keys.

If your deployment needs another runner, change runs-on after you add the fragment.

The job needs id-token: write permission. It uses the vault ID from lpm.json as LPM_VAULT_ID.

The fragment reads LPM_OIDC_POLICY_ID from the GitHub vars context. Create it as a repository variable before the first pull. To use an environment variable instead, add environment: <name> to the job.

The aliases github and gha select the same target.

Print the GitLab.com CI fragment:

lpm setup ci gitlab
lpm setup ci gitlab --env staging

The command prints three items:

  1. A GitLab CI job fragment with an LPM_OIDC_TOKEN identity token
  2. An lpm env oidc allow command for the numeric project ID
  3. An instruction to configure the returned policy ID as LPM_OIDC_POLICY_ID

The identity token uses the https://lpm.dev audience. The checked-out lpm.json file supplies the vault ID.

The command prints output only. It does not create or change .gitlab-ci.yml.

Run the printed authorization command from a logged-in development machine. Then add the job fragment to .gitlab-ci.yml.

The authorization command also uploads protected material for the personal env project. Continue only when LPM CLI reports that CI escrow is enabled.

Create LPM_OIDC_POLICY_ID as a GitLab CI/CD variable before the first pull. Mark it protected only when every branch or tag allowed by the OIDC policy is protected.

The alias gitlab-ci selects the same target. Self-managed GitLab issuers are not supported for this workflow.

JSON output

All setup modes support --json. The workflow targets return the generated text without human instructions on stdout:

lpm setup ci github-actions --env staging --json > setup.json
jq -r '.workflow' setup.json
jq -r '.authorization_command' setup.json
FieldWorkflow target result
successtrue when generation succeeds
platformgithub-actions or gitlab, including when you use an alias
environmentThe selected secret environment
workflow_pathThe suggested workflow file
workflowThe YAML fragment
authorization_commandThe policy command with placeholders to replace
policy_instructionWhere to configure LPM_OIDC_POLICY_ID

The npmrc and local modes write their files and return redacted metadata. They never print the bearer token in JSON.

For CI npmrc output, oidc reports an exchange during this run. recovered reports completion of a pending token retirement.

Recover an interrupted setup

If lpm setup local reports an interrupted token replacement, run the same command again. Use the same registry URL.

lpm setup local --registry https://registry.example.com

If CI setup reports an interrupted retirement, run lpm setup ci npmrc again with the same registry.

The protected file retains the replacement and recovery information. A retry reuses that replacement, even with --oidc or a different environment token.

If you want to switch to CI setup, finish the pending local replacement first. Then run lpm setup ci npmrc.

If .npmrc changes during a registry request, setup stops before it overwrites the edit. Keep the protected recovery block and retry.

A malformed or already-expired replacement response also leaves local setup recovery state for a retry.

If a generated local block belongs to another registry, use that registry URL for recovery. LPM CLI does not move the token between registries.

Flags

CommandFlagPurpose
lpm setup ci npmrc-r, --registry <URL>Use another LPM-compatible registry base URL
lpm setup ci npmrc--oidcRequire a CI OIDC exchange without fallback, unless completing a pending retirement
GitHub Actions or GitLab CI--env <NAME>Set the secret environment in the workflow and policy command. The default is production
lpm setup local-d, --days <DAYS>Set the read-only token lifetime from 1 through 90 days. The default is 30

Use only the flags listed for the selected target. The npmrc target rejects --env. The GitHub Actions and GitLab targets reject --registry and --oidc. The aliases use the same rules.

An invalid flag stops the command before it writes a file or prints a workflow fragment.

--env accepts 1–64 ASCII letters, digits, hyphens, underscores, or periods. The name cannot contain .. or equal __index__.

--json returns structured output for every mode. These commands require no interactive confirmation when credentials are already available.

See also