SnapEnv
SnapEnv is a secure environment-variable manager: encrypted storage per project/environment, a CLI, a Kubernetes operator, and a REST API. This skill covers driving all of them on a user's behalf.
Quick reference
snapenv login --token snp_live_... # one-time, or set SNAPENV_TOKEN
snapenv pull --env prod # write variables to ./.env
snapenv pull --env prod --stdout # print instead of writing a file
snapenv push --env dev # upload a local .env (additive — never deletes remote keys)
snapenv diff --env prod # compare local .env to remote, exit 1 on drift
snapenv projects # list projects + their UUID (needed for --project)
snapenv run --env prod --only DATABASE_URL -- node server.js # inject without touching diskNon-interactive/CI mode: set SNAPENV_TOKEN, SNAPENV_PROJECT, SNAPENV_ENV and every command above runs without a config file or login step.
Ground rules for this skill
- Prefer
snapenv runoversnapenv pullwhenever you're about to execute or test something.runinjects variables into the child process (or asplaceholders in its arguments) without ever writing them to a file or printing them — and it scrubs any exposed value from the command's own stdout/stderr as it streams.pullwrites real plaintext to.env; only use it when the user's workflow genuinely needs a file on disk (e.g. a framework that only reads.envat boot). - Never echo, log, or repeat a secret value back to the user unless they explicitly ask to see it decrypted. Pulling into
.envor injecting viarunis enough — don'tcat .envafterward to "confirm" it worked. runrequires an explicit scope (--only KEY1,KEY2or--all, optionally with--except). There's no default — pick the narrowest scope the task actually needs, not--allout of convenience.- Don't invent variable names. If you reference a
placeholder or a key in--onlythat doesn't exist in the environment,runfails loudly before the command starts — that's intentional, treat it as a signal to runsnapenv diffor check the dashboard rather than guessing. pushis additive, never destructive — keys missing from the local file are left alone remotely. Deleting a key requires the dashboard or a directDELETEAPI call; don't assumepushcan do it.- A project UUID is required for most commands (
--project, or$SNAPENV_PROJECT). Get it fromsnapenv projectsor the dashboard URL (dash.snapenv.io/projects/<uuid>).
When to reach for each reference file
Load these only as needed — don't read all of them up front.
- CLI — every command, flag, exit code, GitHub Actions and non-interactive/CI patterns → reference/cli.md
- Kubernetes operator & Helm — the
SnapEnvSecretCRD, installing the operator, auto-restart-on-change, and wiring SnapEnv into a Helm chart's ownvalues.yaml/templates → reference/operator.md - REST API — direct HTTP access when there's no CLI/operator in the picture (custom tooling, another language) → reference/api.md
- Access & permissions — access-token scopes, the workspace/project/environment role model, who can read/write which environment → reference/permissions.md
- Variables — variable references (composing one variable from another), expiry, environments, how encryption works → reference/variables.md
- Webhooks — notifying Slack or an HTTP endpoint when variables change → reference/webhooks.md
Typical tasks
"Set up SnapEnv for this project" — check for an existing ~/.config/snapenv/config.json or SNAPENV_* env vars first; if absent, ask the user for an access token (dashboard → Settings → Access tokens) rather than generating or guessing one. Then snapenv projects to find/confirm the project UUID.
"Run the tests/dev server with prod-like secrets" — use snapenv run --env <env> --only <the specific keys needed> -- <command>, not pull. Ask the user which keys before defaulting to --all.
"Deploy this to Kubernetes" — see reference/operator.md. If the target already uses a Helm chart, wire SnapEnv in as chart values/templates (documented there) rather than hand-applying a one-off SnapEnvSecret YAML outside the chart's lifecycle.
"Why doesn't my local .env match prod" — snapenv diff --env <env>, not a manual pull-and-compare.
"Add a new required secret across all environments" — this touches real, live secrets; confirm the exact key name and which environments with the user before writing anything, the same as any other irreversible/shared-state action.