Command-line companion to StartSimpli Vault. Exchange an environment access key for all its secrets — AWS Secrets Manager / Doppler style — with no per-secret round-trip and no vendor lock-in.
The headline:
eval "$(simpli exchange creds --env quinns-mac)"
# every secret in the quinns-mac env is now in the current shell as $KEY=value pairs.Published to npm:
npm i -g @startsimpli/cli # or pnpm add -g, or yarn global add
which simpli # /usr/local/bin/simpli (or your prefix)Or run straight from the monorepo:
pnpm --filter @startsimpli/cli build
node packages/cli/dist/index.js configure --api-url https://api.startsimpli.com ...| Command | Purpose |
|---|---|
simpli configure --api-url <url> --env <slug> --key <access-key> |
Store the vault API URL + a named env's access key. Writes ~/.config/simpli/config.json mode 0600. |
simpli exchange creds --env <slug> [--format <fmt>] [--output <file>] |
Fetch every secret in the env. Outputs to stdout by default, or to a file (also 0600). |
simpli run --env <slug> -- <command> [args…] |
Run any command with the env's secrets injected as process env vars. Nothing written to disk. |
simpli envs |
List the environments stored in your local config + their API URLs. |
export (default), dotenv, json, yaml.
# Headline: pop into current shell
eval "$(simpli exchange creds --env quinns-mac)"
# Write to a file (created mode 0600)
simpli exchange creds --env prod --format dotenv --output .env
# Pipe into another tool
simpli exchange creds --env prod --format json | jq '.STRIPE_KEY'
# YAML for Kubernetes-shaped consumers
simpli exchange creds --env prod --format yaml > secrets.yaml
# Run something with the secrets injected, leaving no trace on disk
simpli run --env prod -- npm start
simpli run --env prod -- docker compose upThe export format uses POSIX-safe single-quote escaping (' → '\'') so values containing quotes, dollar signs, or newlines round-trip through eval unmodified. The dotenv format double-quotes + escapes \n, \r, \\, ", $. JSON / YAML are vanilla serializers.
Config lives at ~/.config/simpli/config.json (mode 0600). Environment variables override the file for CI / one-off use:
| Env var | Effect |
|---|---|
SIMPLI_API_URL |
Vault API base URL (overrides per-env config) |
SIMPLI_TOKEN |
Environment access key for the --env you pass (overrides per-env config) |
SIMPLI_CONFIG_DIR |
Alternate config location (default ~/.config/simpli) |
Auth is the environment access key, sent as X-API-Key to POST /api/v1/vault/exchange/. The key is an access credential not the encryption key — rotating it never requires re-entering secrets. Invalid / revoked / expired keys return a uniform 401.
The CLI doubles as a small library if you want to script the same operations:
| Export | Purpose |
|---|---|
buildProgram() |
Returns the configured Commander program for embedding / testing. |
FORMATS |
['export', 'dotenv', 'json', 'yaml'] literal tuple. |
formatSecrets(secrets, format) |
Pure formatter — turn a SecretMap into a string in any supported format. |
loadConfig() / saveConfig(cfg) / getEnvConfig(slug) |
Config IO with 0600 perms + env-var overrides. |
exchangeSecrets({ apiUrl, accessKey }) |
Hit the vault exchange endpoint and parse the response, with friendly 401 messages. |
Against the production vault at api.startsimpli.com:
# (one-time) Sign in to vault-web, create environment `quinns-mac`,
# add secrets, mint an access key. The raw key is shown ONCE.
RAW="vault_live_abc123def456..."
simpli configure --api-url https://api.startsimpli.com \
--env quinns-mac \
--key "$RAW"
# → Saved ~/.config/simpli/config.json (1 environment(s)).
simpli envs
# → quinns-mac → https://api.startsimpli.com
# Drop the secrets into your current shell session
eval "$(simpli exchange creds --env quinns-mac)"
echo "$OPENAI_API_KEY" # sk-...
# Or run a command with them injected (no disk write)
simpli run --env quinns-mac -- python my_script.pyIf the key is bad:
simpli: Access key rejected (401). It may be revoked or expired.
cd packages/cli
pnpm vitest run # 14 tests across cli / client / config / format
pnpm tsc --noEmit
pnpm build # produces dist/index.js — the `simpli` binscripts/vault_e2e_happy_path.sh at the monorepo root is a full local e2e: seeds an env via Django shell, configures the CLI against the dev server, runs exchange creds, asserts decryption + bad-key 401.
The CLI is the only tool in the monorepo that talks to the vault API directly outside of vault-web — this is deliberate. Any common HTTP / config / formatting logic that's also useful for other apps belongs in @startsimpli/utils or @startsimpli/api, not here. See monorepo CLAUDE.md rule 9.
Built with
tsupto a single ESM-compatibledist/index.js. Tracked in beadsstartsim-d30.5.*.