Authentication
Log in, log out, check identity, rotate tokens, and configure CI auth.
LPM stores its own auth tokens in your local secure store. It prefers the OS keychain — Keychain on macOS, Credential Manager on Windows, Secret Service-compatible keyrings on Linux — and falls back to encrypted file storage under ~/.lpm/.credentials when the system store is unavailable. Tokens never land in plain text on disk. Multi-registry: separate stored tokens for lpm.dev, npm, and any explicit third-party fallbacks. GitHub and GitLab can also use tokens already managed by gh / glab without copying them into LPM storage.
This page covers every command in the auth surface: login, logout, whoami, token-rotate, setup ci, setup local, and ci.
lpm login
lpm login # alias: lpm l
lpm login --npm
lpm login --github
lpm login --gitlab
lpm login --login-registry https://npm.my-co.com --token <T>Browser-based OAuth flow for lpm.dev. Starts a local HTTP server on a random port, opens your browser to the registry's /cli/login?port=<N> page, captures the redirect token, verifies it via whoami, and stores it in local secure storage (OS keychain when available, encrypted file fallback otherwise). CSRF state is verified end-to-end. The flow times out after 2 minutes waiting for the browser callback.
On success, human output stays on stderr and ends with a compact summary: browser authentication complete, the user, the registry host, and the active secure-storage backend. --json keeps the machine envelope on stdout and includes storage_backend plus storage_degraded.
For npm, lpm login --npm uses npm's browser login by default: LPM asks registry.npmjs.org for a web-login URL, opens it, polls the registry for completion, then stores the returned npm token. This requires an interactive terminal. In --json mode or non-TTY shells, pass --token <T> or set NPM_TOKEN as the explicit fallback.
For CI publishes to npm, you can skip long-lived npm publish tokens by using npm Trusted Publishing. lpm publish --npm and lpm stage publish first look for npm OIDC auth: GitHub Actions runtime tokens with permissions: id-token: write, or NPM_ID_TOKEN from GitLab CI / CircleCI minted with audience npm:registry.npmjs.org. LPM exchanges that ID token for npm's short-lived registry token and falls back to NPM_TOKEN / stored npm auth only when OIDC is unavailable or rejected. This is publish-only; lpm stage list, view, download, approve, and reject still require normal npm token auth.
For GitHub and GitLab, lpm login --github / --gitlab validates your existing host CLI session instead of asking you to paste a token. GitHub uses gh auth token --hostname github.com; GitLab.com uses glab auth token. When that succeeds, LPM stores nothing. Passing --token <T> remains available as an explicit fallback and stores that token in LPM's secure storage. Self-managed GitLab instances use env or stored fallback tokens in this version.
Custom registries stay token-based. Use lpm login --login-registry <URL> --token <T> in scripts; in an interactive TTY without --token, LPM prompts with masked input. Explicit token fallbacks can still record a token-expiry reminder and 2FA/OTP preference for publishing.
| Flag | Effect |
|---|---|
--npm | Browser-login to registry.npmjs.org; --token / NPM_TOKEN are explicit fallbacks |
--github | Use existing gh auth for GitHub Packages, or store an explicit fallback token with --token |
--gitlab | Use existing glab auth for GitLab.com Packages, or store an explicit fallback token with --token |
--login-registry <URL> | Log in to a custom npm-compatible registry with a token |
--token <T> | Explicit token fallback for npm, GitHub, GitLab, or a custom registry |
For lpm.dev, if you're already logged in, lpm login reports the existing identity and exits without re-authenticating. Third-party login commands refresh or re-check the selected auth source.
lpm logout
lpm logout # alias: lpm lo — log out of lpm.dev
lpm logout --revoke # also revoke the token on the server
lpm logout --npm # log out of npm (lpm.dev session is left alone)
lpm logout --github
lpm logout --gitlab
lpm logout --logout-registry https://npm.my-co.com
lpm logout --all # clear every stored registry token, lpm.dev includedScope rule for per-registry flags. With no flags, lpm logout clears the lpm.dev session only. Passing one of --npm / --github / --gitlab / --logout-registry <URL> clears only that target — your lpm.dev session stays signed in. Use --all to clear everything in one shot.
For GitHub and GitLab, logout clears only LPM-stored fallback tokens. gh and glab sessions remain managed by those tools.
--revoke (lpm.dev only) also unpairs any browser/desktop sessions paired against your current LPM token. The unpair is best-effort — it won't fail the logout if the registry can't reach the pairing endpoint.
Human output shows the local-session cleanup first, then prints Revoked server-side token only when --revoke succeeds, and finishes with Done · signed out of lpm.dev.
| Flag | Effect |
|---|---|
--revoke | Also revoke the token server-side + unpair browser sessions (lpm.dev only) |
--npm / --github / --gitlab | Clear that registry's token only — leaves lpm.dev signed in |
--logout-registry <URL> | Clear a custom registry's token only |
--all | Clear every stored token (lpm.dev + npm + GitHub + GitLab + every custom registry) |
lpm whoami
lpm whoamiPrints the currently logged-in identity for lpm.dev, plus:
- Plan tier, MFA status, pool access flag
- Storage / private-package usage against your plan's limits — with an OVER LIMIT warning when usage exceeds them (publishing and invites are restricted in that state)
- Available Scopes — your personal
@lpm.dev/<profile>.*plus one row per organization you belong to (@lpm.dev/<org-slug>.*) with your role - External Registries — npm, GitHub, GitLab, and custom registry auth sources, including host-CLI-backed GitHub/GitLab auth when available
- Token expiry warnings if any registry token is approaching the reminder window you set during
lpm login - Secure storage backend for the active stored lpm.dev session, with a warning when the encrypted file fallback is active
--json returns the same data structurally: {username, email, plan, mfa_enabled, has_pool_access, usage{storage_bytes, private_packages}, limits{storage_bytes, private_packages}, orgs[{slug, name, role}], registries[{name, status, storage_backend, storage_degraded}], storage_backend, storage_degraded}. storage_backend is "keychain", "encrypted_file_fallback", or null when the active auth source is not stored by LPM.
lpm token-rotate
lpm token-rotateServer-side rotation for the lpm.dev token only: creates a new token, invalidates the old one, and stores the new one in local secure storage. Use after any suspected leak. The new token's expiry (if the server returns one) is recorded for lpm whoami's warning system. There's no equivalent for npm / GitHub / GitLab — rotate npm through lpm login --npm, rotate host-CLI-backed GitHub/GitLab auth in gh / glab, or replace an explicit fallback with lpm login --<target> --token <T>.
lpm setup has two explicit subcommands:
lpm setup ciwrites a project.npmrcfor CI/CD use.lpm setup localmints a read-only local-development token and writes it into.npmrc.
This is separate from lpm ci setup <platform>, which only prints workflow snippets. It does not write .npmrc.
lpm setup ci
lpm setup ci # generate .npmrc with stored token
lpm setup ci --oidc # exchange a CI OIDC token at runtime
lpm setup ci --proxy # route ALL npm traffic through lpm.dev (Pro/Org)
lpm setup ci --scoped # only @lpm.dev/* through lpm.dev (default)
lpm setup ci -r https://lpm.dev # override the registry URLGenerates an .npmrc in the current project directory for CI/CD environments. Other tools (npm, pnpm, yarn) can then install @lpm.dev/* packages from CI. On Unix, the file is set to 0o600 (owner read/write only) since it embeds the auth token.
| Flag | Effect |
|---|---|
-r, --registry <URL> | Override the registry URL written to .npmrc |
--oidc | Exchange an OIDC token at runtime instead of using a stored one |
--proxy | Route ALL npm traffic through lpm.dev (Pro/Org feature for dependency visibility) |
--scoped | Default — only @lpm.dev/* is routed through lpm.dev |
--proxy and --scoped are mutually exclusive.
When neither a stored token nor an OIDC token is available, the generated .npmrc falls back to a literal ${LPM_TOKEN} placeholder so CI can interpolate it at runtime.
Under --json, lpm setup ci still writes the on-disk .npmrc. The JSON envelope ({success, path, content, uses_env_var, oidc, proxy, storage_backend, storage_degraded}) is safe for logs and templating because its content field always uses the ${LPM_TOKEN} placeholder, even when the on-disk file carries a real token at 0o600. storage_backend is null for OIDC, env-var, or placeholder auth sources, and reports the stored-auth backend when the token came from a local LPM session.
lpm setup local
lpm setup local # 30-day read-only .npmrc token (default)
lpm setup local -d 7 # 7-day token
lpm setup local --proxy # route ALL npm traffic through lpm.devGenerates a read-only .npmrc token for local development — narrower scope than the full session token, with a configurable validity window. Useful when you want a teammate or local tool to install LPM packages without granting publish capability. The command also adds .npmrc to .gitignore automatically so the embedded token can't get committed by accident.
Human output includes the token expiry timestamp and validity window.
| Flag | Effect |
|---|---|
-d, --days <N> | Token validity in days (default 30) |
--proxy | Route ALL npm traffic through lpm.dev (Pro/Org) |
--scoped | Default scoped routing |
lpm ci
lpm ci env # auto-detect CI platform, output env vars
lpm ci env --env=staging # use the staging env file
lpm ci env --output=ci-env.txt # write to a file
lpm ci setup github-actions # print an OIDC workflow snippet + auth commandCI/CD helpers, with two complementary subcommands:
lpm ci env— emits the loaded env vars in a CI-native format. Auto-detection: GitHub Actions runners get GitHub's masked-output format (echo "::add-mask::…"-style); Vercel gets dotenv (key=value); everything else (GitLab CI, CircleCI, Bitbucket, generic POSIX runners) gets shell-export lines that work in any CI.--env=<mode>selects which env file is loaded;--output=<file>writes a dotenv-formatted copy to the given path regardless of the auto-detected CI format (the stdout stream still uses the CI-native shape). Secret-marked vars fromlpm.json > envSchemaare masked in the CI-native output where the platform supports it.lpm ci setup <platform>— prints an OIDC-wired starter workflow snippet plus thelpm env oidc allowauthorization command to run after committing it. It does not write.npmrc; uselpm setup cifor that. Currently supportsgithub-actions(aliases:github,gha) andgitlab(alias:gitlab-ci). The GitLab snippet mintsLPM_OIDC_TOKENvia theid_tokensblock withaud: https://lpm.dev, which is the canonical input the registry-exchange path expects.
Token storage
| Platform | Backend |
|---|---|
| macOS | Keychain (security framework) |
| Linux | Secret Service-compatible keyring (via keyring) |
| Windows | Credential Manager |
Service name: lpm-cli. Account names are scoped per registry — lpm.dev, npm, GitHub, GitLab, and custom registries each get their own keychain entry. lpm logout --all walks every stored entry and clears them.
If the system keychain is unavailable (sandboxed environment, headless Linux without D-Bus, locked store), the CLI falls back to encrypted file storage at ~/.lpm/.credentials instead of storing tokens in plaintext.
You can see the active backend in lpm login, lpm whoami, lpm whoami --json, lpm setup ci --json, and lpm doctor. The exact human wording is secure storage backend: keychain or secure storage backend: encrypted file fallback. The encrypted fallback is valid and encrypted, but lpm doctor treats it as degraded because it does not have the same OS-managed per-app protections as the keychain-backed path.
See also
- Registries — how the CLI routes between lpm.dev, npm, and private registries
lpm publish— needs you logged in to the target registry- Environment variables —
LPM_TOKEN,LPM_OIDC_TOKEN .npmrcformat — the filesetup ciandsetup localwrite