Vaultlier

CLI

Manage projects, schema, and secret values from the command line. Every command exits with a meaningful status code for scripting.

Run vaultlier --help for a summary, or vaultlier <command> --help for details on any command.

init

Sets up the current directory. Installs the dependency if needed, offers a browser login when you have no account credentials, lets you pick or create a project, and always writes vaultlier.config.json. Legacy vaultlier.json files are still accepted. It can also generate a typed SDK client at lib/vaultlier/vaultlier.ts. It also creates or updates .env with a VAULT_MASTER_KEY="" placeholder for self-hosted portal deployments.

Terminal
vaultlier init

# Non-interactive (CI):
vaultlier init --project-id=prj_29ec67d64dd1 --api-key=vlt_live_...

# Skip the generated client and wire createClient yourself:
vaultlier init --no-client

# Or choose where the client is generated:
vaultlier init --client=src/vaultlier.ts

The API key is optional at init time — press Enter to skip it. Re-run with --force to overwrite existing metadata.

If VAULT_MASTER_KEY already exists in .env, init leaves the value untouched.

When a client is generated, the path is recorded in vaultlier.config.json so later commands regenerate the same file. If a legacy vaultlier.json is the active config, it is updated in place. If no client path is recorded, those commands leave SDK wiring to you.

login / logout

login authenticates the machine via the OAuth device-code flow: it shows a verification URL and a short code, you approve it in the browser, and the CLI receives an account token. The token is stored per-user in ~/.vaultlier/auth.json with owner-only permissions.

Terminal
vaultlier login    # approve in the browser
vaultlier logout   # remove the stored account token

Account token ≠ project key

The account token only authorizes listing and creating projects. It can never read secrets — that always requires a project API key. Review and revoke device sessions from the portal under Account & devices.

config

Manage the local project binding and credentials.

CommandEffect
config set project=<id>Update vaultlier.config.json, or the active legacy config, and regenerate the typed client when one was generated.
config set apiKey=<vlt_…>Update the local credential cache only; the key is never printed back.
config getShow the current project, masked API key, and account login state.
config verifyRe-validate the project id + API key against the portal.
Terminal
vaultlier config set project=prj_29ec67d64dd1
vaultlier config set apiKey=vlt_live_...
vaultlier config get
vaultlier config verify

scan

Detects environment-variable keys referenced in your code and .env files and offers to reconcile your schema metadata. Values are ignored — only key names are read.

Terminal
vaultlier scan          # report detected keys
vaultlier scan --yes    # reconcile vaultlier.config.json without prompting

To avoid false positives, scan only recognizes established environment-access idioms — never bare SCREAMING_SNAKE_CASE constants:

  • .env / .env.* file keys
  • process.env.X / process.env["X"] (Node.js, Next.js)
  • Deno.env.get("X") (Deno)
  • import.meta.env.X (Vite, Astro, SvelteKit) — framework built-ins like MODE are excluded
  • configService.get("X") / config.get("X") (NestJS @nestjs/config)
  • env("X") / getenv("X") config helpers

Compiled and build output is never scanned — node_modules, dist, build, out, output, framework caches (.next, .nuxt, .svelte-kit, .output), and any outDir declared in your tsconfig.json.

Self-correcting

Each scan reconciles the schema with what your code actually uses. Keys that scan previously added but no longer appear anywhere are removed. Keys you added by hand or with set are never touched — only scan-managed keys are pruned.

audit

Runs a local security review and writes an HTML report. The scanner foundation is dependency-free: it checks project structure, plaintext env files, hardcoded secret patterns, package scripts, and framework-specific public-env hazards.

Terminal
vaultlier audit
vaultlier audit --ai
vaultlier audit --output=security-report.html
vaultlier audit --no-ai

The CLI prints score analytics for structure, exposed unprotected secrets, dependency posture, and framework surface. It detects common frameworks such as Next.js, NestJS, Vite, Angular, Express, and Node.js from package metadata and config files, while skipping common generated output such as node_modules, dist, .next, and build caches.

Pass --ai to call the hosted /v1/audit/analyze endpoint for AI recommendations. The command uses the same project API key resolution order as other portal commands. The portal routes to DeepSeek first, then OpenAI, then Anthropic based on configured provider keys. Pass --no-ai to force local-only scanning.

The AI request sends sanitized audit metadata only: scores, framework names, finding titles, severities, paths, and recommendations. It does not upload source files, .env contents, or secret values.

Metadata-only config update

The full report is written locally (vaultlier-audit-report.html by default). The active config stores only audit.lastRun summary metadata: scores, finding titles, severities, paths, detected frameworks, and optional AI recommendations. Secret values are not stored in the config summary.

push / pull / diff

These sync schema metadata — key names, types, scopes, and environments — with the portal. Secret values are never sent or received by these commands.

  • push — send local schema additions to the portal (additive; nothing is deleted server-side).
  • pull — fetch the portal schema and regenerate the typed client if the project opted into one. Without an API key it falls back to local metadata.
  • diff — show what differs between local and portal.
Terminal
vaultlier push --env=prod
vaultlier pull --env=prod
vaultlier diff --env=prod

set

Writes one or more KEY=VALUE pairs to a single environment. Keys must already exist in the schema and be scoped to the target environment — both are checked locally before any value leaves your machine. Values are sealed server-side as new immutable versions. Requires an API key with the member role or higher.

Terminal
vaultlier set DATABASE_URL=postgres://prod-db/main --env=prod
vaultlier set STRIPE_SECRET=sk_live_... FEATURE_NEW_FLOW=true -e prod

If the target environment does not exist yet, set offers to create it (pass --yes to skip the prompt in CI). It declares the environment through an additive schema push, then writes the values.

Terminal
vaultlier set DATABASE_URL=postgres://wip-db --env=working --yes

unset

Removes stored secret values for one or more keys from a single environment. It is the counterpart to set: schema metadata stays intact, so the keys can be set again later.

Terminal
vaultlier unset DATABASE_URL --env=prod
vaultlier unset STRIPE_SECRET FEATURE_NEW_FLOW --env=prod --yes

Removal is destructive and cannot be undone, so unset asks for confirmation unless you pass --yes. Values are never read, printed, or written to disk. You may pass KEY=VALUE entries copied from a set command; the value is ignored and only the key name is sent to the portal. The command reports both removed keys and keys that were already not set.

update

Reviews the schema variables for an environment and drops the ones you no longer want. Only key names and scopes are read — secret values are never touched. On a terminal it opens an interactive checklist; pass --env to skip the environment picker.

Terminal
vaultlier update --env=prod   # review prod's schema vars
vaultlier update              # pick the environment from a list

In the checklist, move with the arrow keys (or j/k), toggle a var with Space, and apply with Enter. Everything starts checked (kept); unchecked vars are dropped. A var scoped to several environments is narrowed — only the selected environment is removed from its scopes — while a var scoped to a single environment (or reviewed under --env=all) leaves the schema entirely.

For CI, drop keys non-interactively with --drop and confirm with --yes:

Terminal
vaultlier update --env=prod --drop=OLD_FLAG,LEGACY_URL --yes

Drops apply locally and remotely

After updating vaultlier.config.json (or the active legacy config) and any generated client, update pushes the reduced schema to the portal so the remote matches. Without an API key it drops locally only and reminds you to run vaultlier push to propagate the change.

dev

Starts a small management UI for the one project bound in your local vaultlier.config.json (or legacy vaultlier.json), bound to loopback (http://127.0.0.1:9090). It is a tiny portal that stays in sync with the remote Vaultlier store — every change is written straight through. From it you can:

  • View and edit (overwrite) environment variable values per environment.
  • View and manage environments — create, rename, and delete.
  • Manage the storage backend(Vaultlier, S3, Postgres), which updates the project's remote settings.
Terminal
vaultlier dev
vaultlier dev --port=4000

The API key stays on your machine

The browser talks only to the loopback server, which proxies to the portal using a key resolved from --api-key, VAULTLIER_API_KEY, or the local credential cache — the key is never sent to the page. Value edits and environment changes need a member key; storage changes need an admin key, exactly as the portal enforces. Without a key the UI is read-only.

whoami

Prints the resolved project context: project id, environments, and the masked API key.

Terminal
vaultlier whoami

generate-key

Prints a fresh VAULT_MASTER_KEY — 32 cryptographically-random bytes, base64-encoded — for a portal deployment to seal and unseal secret values. This is only needed when you self-host the portal; the hosted service is already configured. vaultlier generate key and vaultlier -g key are accepted aliases.

Terminal
# print a key (also: vaultlier generate key)
vaultlier generate-key

# the key prints on stdout, setup notes on stderr — so you can capture just the key:
vaultlier generate-key 2>/dev/null
KEY=$(vaultlier generate-key 2>/dev/null)

Set once; never store it casually

The command does not store, cache, log, or transmit the key — it only prints it. Set it as a server environment variable (VAULT_MASTER_KEY) on your deployment and treat it like a root credential. Changing or losing it makes already-sealed secrets unrecoverable, because each value records the key generation it was sealed with.

Flag conventions

Every value flag has a canonical --kebab-case long form; common ones also have a single-letter short form. Both --flag=value and --flag value work.

ShortLongAliasesUsed by
-e--env--environmentpull, push, diff, set, unset, update
-k--api-key--apiKeyall portal commands
--api-url--apiUrlall portal commands
--project-id--projectIdinit
-p--portdev
-o--output--generate, --generate-env, audit
--clientinit
--aiaudit
--no-aiaudit
--no-clientinit
--dropupdate
-y--yesprompts
-f--forceinit, generated .env
-h--helpeverywhere

Output & scripting

Commands print status-prefixed lines and show a spinner while talking to the portal. Styling degrades gracefully:

  • Colors and spinners activate only on an interactive terminal.
  • They are suppressed when output is piped or CI is set, so logs stay plain.
  • NO_COLOR disables colors; FORCE_COLOR forces them.
  • Spinners render on stderr, keeping stdout clean for scripting.