Skip to content

qosha1/simpli-cli

Repository files navigation

@startsimpli/cli — simpli

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.

Install

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 ...

Commands

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.

Output formats (--format)

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 up

Output value escaping

The 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 & auth

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.

Public TypeScript surface

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.

Worked example end-to-end

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.py

If the key is bad:

simpli: Access key rejected (401). It may be revoked or expired.

Verification

cd packages/cli
pnpm vitest run     # 14 tests across cli / client / config / format
pnpm tsc --noEmit
pnpm build          # produces dist/index.js — the `simpli` bin

scripts/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.

Shared-first

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 tsup to a single ESM-compatible dist/index.js. Tracked in beads startsim-d30.5.*.

About

simpli — exchange a StartSimpli Vault environment access key for all its secrets (AWS Secrets Manager / Doppler style)

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors