DEV Community

Cover image for From Slack-Pasted .env Files to SnapEnv — A 10-Minute Setup Guide
Mohammed Tayeh
Mohammed Tayeh

Posted on AI-assisted

From Slack-Pasted .env Files to SnapEnv — A 10-Minute Setup Guide

If your team's secrets management process looks like this —

  • a .env.example file that's permanently out of date
  • the real .env living in three people's Slack DMs
  • nobody quite sure which value is actually live in production
  • "wait, who has the prod database password?"

— this guide walks through replacing it with SnapEnv in about 10 minutes: dashboard, CLI, and a scoped token for CI. No credit card, no sales call.

Part 1 of 3 — next up: running SnapEnv on a bare Linux server with systemd, then the Kubernetes operator with Helm.

🎉 Product Hunt readers: use code HELLOSNAP for the Pro plan free for 3 months — from Workspace → Plan & Billing, click Upgrade your plan, then redeem a coupon. No credit card needed. Limited to the first 100 redemptions, valid through Jan 1, 2027.

What we're building

By the end of this guide you'll have:

  • A project with dev, staging, and prod environments
  • Variables added two ways (one-by-one, and bulk-imported from an existing .env)
  • The snapenv CLI installed and pulling secrets into a local .env
  • A scoped access token, ready to hand to CI

1. Create your workspace

Sign up at dash.snapenv.io — a workspace is created automatically, and you land straight on the Projects overview:

SnapEnv dashboard — projects overview

Every project here tracks its own set of environments and shows you, at a glance, how many variables exist and when something last changed.

2. Create a project

Click New project. Give it a name, an optional description, and pick which environments it needs. dev, staging, and prod are selected by default, and you can add more later:

Creating a new project

Every project also gets a UUID (visible at the top of its Variables page) — that's the real identifier the API, the CLI's --project flag, and SNAPENV_PROJECT all use, not the display name.

prod is marked protected by default — more on why that matters in the team access section below.

3. Add your first variables

Open the project and you land on its Variables page, one tab per environment. There are two ways to get variables in:

One at a time, with the type explicitly set to Plain or Secret (secret values are masked in the UI and in every API response unless you explicitly reveal them):

Add variable modal

Or bulk-imported — paste an existing .env file directly in, and SnapEnv parses it, auto-detects which keys look like secrets, and lets you pick which environments to add them to:

Paste .env to bulk-import variables

Either way, values are encrypted (AES-256-GCM, unique key per project) before they ever touch the database — SnapEnv's own team can't read them, and neither can anyone without explicit access to that environment. Here's the result:

Populated variables table with secrets masked

Notice the CLI hint panel in the top right of every project page — it always shows the exact snapenv pull command for whichever environment tab you're looking at. That's your cue for the next step.

4. Install the CLI

The snapenv binary is a single static executable — no runtime, no dependencies:

curl -fsSL https://get.snapenv.io/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

That detects your OS/architecture and installs to ~/.local/bin/snapenv. It supports macOS (amd64/arm64) and Linux (amd64/arm64) out of the box.

5. Authenticate and pull

Grab an access token from Settings → Access tokens → New token (walked through in detail in step 7 below), then:

$ snapenv login --token snp_live_xxxxxxxxxxxxxxxxxxxx
✓ Logged in — credentials saved to ~/.config/snapenv/config.json

$ snapenv pull --env dev
✓ 5 variables written to .env
Enter fullscreen mode Exit fullscreen mode

That's it — your local .env is populated, chmod 600, ready to load into whatever's running your app locally. Every project has its own UUID, so if you're juggling multiple services, pin the CLI to one with --project (or SNAPENV_PROJECT) instead of switching context every time.

6. Promote and compare environments

Once dev is in good shape, push it forward or diff it against what's already live:

# Push your local .env up to staging (additive — nothing gets deleted remotely)
$ snapenv push --env staging
✓ 3 created, 2 updated

# Check what would change before you push to prod
$ snapenv diff --env prod
~ DATABASE_URL   (value differs)
+ FEATURE_FLAG   (remote only — not in local file)
- DEBUG_MODE     (local only — not in remote)
Enter fullscreen mode Exit fullscreen mode

diff exits non-zero when it finds a difference, which makes it a natural CI gate — wire it into a pipeline step and it'll fail the build the moment prod config drifts from what's in source control (or vice versa).

7. Invite your team — permissions that default to safe

SnapEnv enforces three layers of access control, and the defaults are deliberately conservative: a Developer role gets write on unprotected environments like dev/staging, but no default access to prod at all. An Admin or Owner has to explicitly grant a developer read or write on a protected environment — it's opt-in, not opt-out.

Invite teammates from Workspace → Team → Invite, then fine-tune each person's per-environment access from the project's Team & Access tab. Every invite, role change, and access grant is written to the audit log automatically — no separate setup required.

8. Create a scoped token for CI

Humans authenticate with GitHub OAuth or email; machines (CI, the Kubernetes operator, cron jobs) use snp_live_ access tokens instead. Create one from Access Tokens → New token:

Access tokens page

New access token modal

Three things worth setting deliberately here, every time:

  • ScopeRead-only if this token only ever needs to pull. Save Read & write for anything that also pushes.
  • Project access — pin it to one project unless you genuinely need workspace-wide access.
  • Environment access — a CI token for staging deploys has no business being able to read prod.

The plaintext token is shown exactly once — copy it straight into your CI provider's secret store (GITHUB_TOKEN/repo secrets, etc.) or a Kubernetes Secret. If you ever lose it, rotate it; the old one is revoked the instant you do.

# .github/workflows/deploy.yml
- name: Pull secrets
  env:
    SNAPENV_TOKEN: ${{ secrets.SNAPENV_TOKEN }}
    SNAPENV_PROJECT: ${{ vars.SNAPENV_PROJECT }}
  run: snapenv pull --env prod
  # GITHUB_ACTIONS=true is already set by the runner, so every variable
  # is also appended to $GITHUB_ENV automatically — no extra wiring needed.
Enter fullscreen mode Exit fullscreen mode

What's next

That's the core loop: dashboard for humans, CLI for machines, one source of truth for both. Full reference docs live at docs.snapenv.io if you want to go deeper on any step above.

This is part 1 of a 3-part series on running SnapEnv in production:

  1. Dashboard + CLI for developers (this guide)
  2. Running SnapEnv on a bare Linux server with systemd — coming up next: pulling secrets into a scoped EnvironmentFile and wiring a timer to pick up changes automatically, with no plaintext token in the unit file.
  3. Kubernetes: the operator, auto-reload, and Helm — syncing variables straight into native Secret objects, auto-restarting Deployments when they change, and a drop-in pattern for adding SnapEnv as a secrets source in your own Helm chart.

🎉 One more reminder: code HELLOSNAP gets you the Pro plan free for 3 months, first 100 redemptions — snapenv.io

Top comments (0)