Getting Started

dotsec replaces your .env file with a .sec file: same shape, same workflow, but encrypted and committed to git. Your tools don't notice — the integration is dotsec run -- <whatever you were running before>.

Install

npm install -g dotsec

npm-only, bundles a native binary for macOS / Linux / Windows. Dev-dependency and one-shot npx patterns: Setup → Install.

Already have a .env?

Then you're two commands from done:

dotsec import -y                 # .env → encrypted .sec
dotsec run -- node server.js    # ← whatever you were running before

Check what happened, then commit:

dotsec show       # decrypted view, values masked
git add .sec      # .sec goes into git
rm .env           # no more .env files

Your private key landed in .sec.key, which dotsec auto-added to .gitignore. Stash a copy in your password manager.

Starting fresh?

dotsec set API_KEY sk-live-xxx --encrypt   # auto-creates .sec + keypair
dotsec set PORT 3000                       # plaintext var
dotsec run -- node server.js

Works with anything

dotsec run injects decrypted env vars into any child process — there's no SDK, no framework adapter, nothing to integrate:

dotsec run -- node server.js
dotsec run -- npm run dev
dotsec run -- python manage.py runserver
dotsec run -- cargo run
dotsec run -- go run ./cmd/api
dotsec run -- rails server
dotsec run -- docker compose up
dotsec run -- terraform apply

If it reads environment variables, it works. The child gets a real PTY, so colors and interactivity survive.

How it works

.env (plaintext, gone)                .sec (encrypted, committed)
┌─────────────────────────┐           ┌────────────────────────────┐
│ DATABASE_URL=postgres://│  encrypt  │ # @dotsec(format=v3,       │
│ API_KEY=sk-live-xxx     │ ───────▶  │ #   mac=..., dek=...)      │
│ DEBUG=true              │           │ DATABASE_URL=ENC[base64]   │
└─────────────────────────┘           │ API_KEY=ENC[base64]        │
                                 ◀─── │ DEBUG=true                 │
                               decrypt└────────────────────────────┘

Each secret is encrypted individually with AES-256-GCM using a data encryption key (DEK). The DEK is wrapped by your keypair (or AWS KMS) and stored in the @dotsec(...) directive. Per-value encryption is what makes .sec files git-mergeable — two teammates changing different secrets merge cleanly.

Team sharing

Share the .sec.key file over a secure channel (a password manager, not Slack). For CI, set DOTSEC_PRIVATE_KEY as a secret — copy-paste recipes in CI/CD.

Where to go next

You want to…Read
Install as a dev dependency, use AWS KMS, run multiple environmentsSetup
Add types, validation, and push targets to your varsDirectives
Wire dotsec into GitHub Actions / GitLabCI/CD
Understand the crypto and the threat modelEncryption · Security
Use dotsec programmatically or generate TypeScript typesLibrary
Fix an error you just hitTroubleshooting