@dotenc/cli 0.3.4 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,56 +1,214 @@
1
- # ![dotenc](./assets/logo.png "dotenc logo")
2
- 🔐 Secure, encrypted environment variables that live in your codebase
1
+ # ![dotenc](/assets/logo.jpg "dotenc logo")
2
+
3
+ [![NPM Version][npm-image]][npm-url]
4
+ [![Github License][license-image]](LICENSE)
5
+ [![NPM Downloads][downloads-image]][npm-url]
6
+
7
+ 🔐 Git-native encrypted environments powered by your SSH keys
8
+
9
+ ## 30-Second Example
10
+
11
+ ```bash
12
+ dotenc init # pick your SSH key, choose a name
13
+ dotenc env edit alice # add your personal secrets
14
+ dotenc dev npm start # run with your encrypted env
15
+ ```
16
+
17
+ Encrypted `.env.alice.enc` committed.
18
+ No external services.
19
+ Uses your existing SSH keys.
20
+ Done.
3
21
 
4
22
  ## Features
5
23
 
6
24
  - 🔒 Uses the battle-tested AES-256-GCM encryption algorithm
7
- - 🔑 Keys can be exported anytime - no vendor lock-in
25
+ - 🔑 Uses your existing SSH keys - no extra key management
8
26
  - 🚀 Secure command running with on-the-fly decryption
9
27
  - ✍️ Easy and secure environment variable editing
10
28
  - 🌍 Supports multiple and extensible environments
11
- - 🔄 Offers a simplified key rotation process
29
+ - 👤 Personal encrypted environments per developer
30
+ - 🔄 Automatic data key rotation on edits
31
+ - 🛡️ Supports both RSA and Ed25519 SSH keys
32
+
33
+ ## Table of Contents
34
+
35
+ - [30-Second Example](#30-second-example)
36
+ - [Features](#features)
37
+ - [Why?](#why)
38
+ - [Security Model](#security-model)
39
+ - [How It Works](#how-it-works)
40
+ - [Project Structure](#project-structure)
41
+ - [Installation](#installation)
42
+ - [Basic Usage](#basic-usage)
43
+ - [Setup](#setup)
44
+ - [Creating a new environment](#creating-a-new-environment)
45
+ - [Listing environments](#listing-environments)
46
+ - [Editing an environment](#editing-an-environment)
47
+ - [Run commands on an environment](#run-commands-on-an-environment)
48
+ - [Checking your identity](#checking-your-identity)
49
+ - [Team Collaboration](#team-collaboration)
50
+ - [Granting access to a new team member](#granting-access-to-a-new-team-member)
51
+ - [Revoking access from a team member](#revoking-access-from-a-team-member)
52
+ - [Listing access](#listing-access)
53
+ - [Offboarding a Team Member](#offboarding-a-team-member)
54
+ - [CI/CD Integration](#cicd-integration)
55
+ - [1. Generate a dedicated CI key](#1-generate-a-dedicated-ci-key)
56
+ - [2. Add the key and grant access](#2-add-the-key-and-grant-access)
57
+ - [3. Set the private key in your CI provider](#3-set-the-private-key-in-your-ci-provider)
58
+ - [4. Use dotenc in your CI pipeline](#4-use-dotenc-in-your-ci-pipeline)
59
+ - [GitHub Actions example](#github-actions-example)
60
+ - [Key Management](#key-management)
61
+ - [Supported Key Types](#supported-key-types)
62
+ - [Adding a public key](#adding-a-public-key)
63
+ - [Listing public keys](#listing-public-keys)
64
+ - [Removing a public key](#removing-a-public-key)
65
+ - [Tips](#tips)
66
+ - [How dotenc compares](#how-dotenc-compares)
67
+ - [When NOT to use dotenc](#when-not-to-use-dotenc)
68
+ - [License](#license)
69
+
70
+ ## Why?
71
+
72
+ Managing secrets and environment variables is critical for any modern application, but most solutions rely on third-party services and web dashboards. **dotenc** was created to solve these problems:
73
+
74
+ - **No Vendor Lock-In:** Your secrets and keys live in your codebase and your repository. You're never tied to a third-party provider or forced to migrate if pricing or policies change.
75
+ - **Improved Security:** Eliminate the risk of exposing secrets to external services. All encryption and decryption happen locally, and private keys never leave your machine.
76
+ - **Zero Key Management:** You already have SSH keys. dotenc uses them directly - no custom key generation, no extra files cluttering your home directory, no new workflows to learn.
77
+ - **Better Developer Experience:** No more juggling environment variables in a web UI or struggling to keep them in sync across branches. Everything is managed alongside your code, with simple CLI commands and full Git integration.
78
+ - **Seamless Collaboration:** Onboard or revoke team members with a single command. Grant or remove access per environment, and let Git handle the rest.
79
+ - **Fully Auditable:** Every grant and revoke is tracked within your Git history, so you always know who had access and when changes were made.
80
+ - **PR-Safe Environment Changes:** Environment variable updates live in the same pull request as your feature code. No more "merge → broken build → patch env → rebuild" workflow.
81
+
82
+ ## Security Model
83
+
84
+ - Each environment has its own randomly generated 256-bit data key.
85
+ - Data keys are encrypted per-user using their SSH public key.
86
+ - dotenc uses AES-256-GCM for authenticated encryption.
87
+ - Your repository alone is not enough to decrypt secrets.
88
+ - Access can be revoked at any time.
12
89
 
13
90
  ## How It Works
14
91
 
15
- 1. Environment variables are encrypted using a secure key
16
- 2. Encrypted files (`.env.*.enc`) are committed to your repository
17
- 3. Keys are stored securely and not committed to the repository
18
- 4. The local, git-ignored `.env` file can be used for development
19
- 5. When running commands, variables are decrypted on-the-fly
92
+ 1. dotenc detects your existing SSH keys in `~/.ssh/` (Ed25519 or RSA);
93
+ 2. Your public key is derived and stored in the project (`.dotenc/john.pub`);
94
+ 3. A unique data key is generated for each environment;
95
+ 4. The data key is encrypted with each authorized public key;
96
+ 5. Environment variables are encrypted using the data key with AES-256-GCM;
97
+ 6. Encrypted files (`.env.*.enc`) are committed to your repository;
98
+ 7. When running commands, variables are decrypted on-the-fly using your SSH private key.
99
+
100
+ Your SSH private keys never leave `~/.ssh/`. dotenc reads them in place - nothing is copied, nothing is stored elsewhere.
101
+
102
+ ### Project Structure
103
+
104
+ After setup, your project will look like:
105
+
106
+ ```
107
+ .
108
+ ├── .dotenc/
109
+ │ ├── alice.pub
110
+ │ ├── bob.pub
111
+ │ └── ...
112
+ ├── .env.alice.enc
113
+ ├── .env.production.enc
114
+ ├── .env.development.enc
115
+ └── dotenc.json
116
+ ```
117
+
118
+ Encrypted files are committed to Git. Public keys are stored inside `.dotenc/`. Each developer gets a personal encrypted environment (e.g., `.env.alice.enc`).
20
119
 
21
120
  ## Installation
22
121
 
122
+ ### Homebrew (macOS / Linux)
123
+
124
+ ```bash
125
+ brew tap ivanfilhoz/dotenc
126
+ brew install dotenc
127
+ ```
128
+
129
+ ### Scoop (Windows)
130
+
131
+ ```bash
132
+ scoop bucket add dotenc https://github.com/ivanfilhoz/scoop-dotenc
133
+ scoop install dotenc
134
+ ```
135
+
136
+ ### npm
137
+
23
138
  ```bash
24
139
  npm install -g @dotenc/cli
25
140
  ```
26
141
 
27
- ## Usage
142
+ ### Standalone binary
143
+
144
+ Download the latest binary for your platform from the [GitHub Releases](https://github.com/ivanfilhoz/dotenc/releases) page.
145
+
146
+ ## Basic Usage
147
+
148
+ ### Setup
149
+
150
+ ```bash
151
+ dotenc init
152
+ ```
153
+
154
+ This will interactively guide you through the setup process:
155
+
156
+ 1. Scanning your `~/.ssh/` directory for SSH keys (Ed25519, RSA, etc.);
157
+ 2. Prompting for your username (defaults to your system username);
158
+ 3. Letting you choose which SSH key to use;
159
+ 4. Deriving the public key and storing it in `.dotenc/` (e.g., `.dotenc/alice.pub`);
160
+ 5. Creating a `dotenc.json` configuration file in the root of your project;
161
+ 6. Creating your personal encrypted environment (e.g., `.env.alice.enc`).
162
+
163
+ No keys to generate. If you already have an SSH key (and you probably do), you're ready to go.
164
+
165
+ If you don't have an SSH key yet, just run `ssh-keygen` first - you'll want one anyway.
166
+
167
+ ### Creating a new environment
168
+
169
+ ```bash
170
+ dotenc env create [environment]
171
+ ```
172
+
173
+ This command creates a new encrypted environment file under the specified name (e.g., `.env.development.enc`). Your personal environment is created automatically during `init`.
28
174
 
29
- ### Initialize a New Environment
175
+ ### Listing environments
30
176
 
31
177
  ```bash
32
- dotenc init [environment]
178
+ dotenc env list
33
179
  ```
34
180
 
35
- This will:
36
- 1. Create a new encrypted environment file (`.env.[environment].enc`)
37
- 2. Set up a local `.env` file for development
38
- 3. Create a `dotenc.json` configuration file
181
+ Lists all encrypted environments in the current project.
39
182
 
40
- ### Edit an Environment
183
+ ### Editing an environment
41
184
 
42
185
  ```bash
43
- dotenc edit [environment]
186
+ dotenc env edit [environment]
44
187
  ```
45
188
 
46
189
  Opens your system's default editor to modify the specified environment. To set a custom editor, use the `dotenc config editor` command. It will take precedence over your system's default editor.
47
190
 
48
191
  Example:
192
+
49
193
  ```bash
50
194
  dotenc config editor vim
51
195
  ```
52
196
 
53
- ### Run Commands on an Environment
197
+ ### Run commands on an environment
198
+
199
+ For development, the `dev` command loads both the shared `development` environment and your personal environment automatically:
200
+
201
+ ```bash
202
+ dotenc dev <command> [...args]
203
+ ```
204
+
205
+ Example:
206
+
207
+ ```bash
208
+ dotenc dev node app.js
209
+ ```
210
+
211
+ For explicit environment control, use `run`:
54
212
 
55
213
  ```bash
56
214
  dotenc run --env <environment> <command> [...args]
@@ -59,41 +217,223 @@ dotenc run -e <environment> <command> [...args]
59
217
  ```
60
218
 
61
219
  Example:
220
+
62
221
  ```bash
63
222
  dotenc run -e production node app.js
64
223
  ```
65
224
 
66
225
  You can also specify multiple environments:
226
+
67
227
  ```bash
68
228
  dotenc run -e base,production node app.js
69
229
  ```
70
230
 
71
231
  In the example above, `production` will override any variables also present in `base`.
72
232
 
73
- ### Key management
233
+ ### Checking your identity
74
234
 
75
- To import a key into your machine, use the `key import` command:
76
235
  ```bash
77
- dotenc key import <environment> <key>
236
+ dotenc whoami
78
237
  ```
79
238
 
80
- To export a key from your machine, use the `key export` command:
239
+ Shows your name, active SSH key, fingerprint, and the environments you have access to in this project.
240
+
241
+ ## Team Collaboration
242
+
243
+ In a real-world scenario, you will likely have multiple environments (e.g., `development`, `test`, `production`) and a team of developers who need access to these environments. Let's walk through how to set this up.
244
+
245
+ ### Granting access to a new team member
246
+
247
+ Alice just joined your team and she needs access to the shared environments, except `production`. She already has an SSH key (because of course she does - she's a developer).
248
+
249
+ She sends you her public key (`~/.ssh/id_ed25519.pub`) — it's a public key, so Slack, email, or even a sticky note will do — and you grant her access:
250
+
81
251
  ```bash
82
- dotenc key export <environment>
252
+ git checkout -b grant-alice-key
253
+ dotenc key add alice --from-file alice.pub
254
+ dotenc auth grant development alice
255
+ dotenc auth grant test alice
256
+ git add .
257
+ git commit -m "Grant alice access to development and test environments"
258
+ git push
83
259
  ```
84
260
 
85
- To rotate a key, use the `key rotate` command:
261
+ Now, Alice will be able to decrypt the `development` and `test` environments using her SSH key. No new tools for her to install, no custom keys to generate - just her existing SSH key.
262
+
263
+ ### Revoking access from a team member
264
+
265
+ One of your team members, John, is leaving the company. You need to revoke his access to all environments. To do this, you can run:
266
+
86
267
  ```bash
87
- dotenc key rotate <environment>
268
+ dotenc key remove john
88
269
  ```
89
270
 
90
- ## Use Cases
271
+ This will delete his key from the repository and automatically reencrypt all the environments. Then, commit your changes:
272
+
273
+ ```bash
274
+ git checkout -b revoke-john-key
275
+ git add .
276
+ git commit -m "Revoke John's access to all environments"
277
+ git push origin revoke-john-key
278
+ ```
279
+
280
+ Once merged, he will no longer be able to decrypt any environments.
281
+
282
+ ### Listing access
283
+
284
+ ```bash
285
+ dotenc auth list [environment]
286
+ ```
287
+
288
+ Lists all public keys that have access to the specified environment.
289
+
290
+ ## Offboarding a Team Member
291
+
292
+ Revoking repository decryption does not undo previously granted access to already-seen secrets.
293
+ For proper offboarding, we recommend:
294
+
295
+ 1. `dotenc key remove <user>`
296
+ 2. Rotate external secrets (database passwords, API tokens, etc.)
297
+ 3. (Optional) `dotenc env rotate <environment>` to rotate the environment data key
298
+ 4. Deploy updated configuration
299
+
300
+ ## CI/CD Integration
301
+
302
+ CI runners and build servers need their own identity to decrypt environments. The approach is the same as local development: generate a key, grant access, and provide the private key at runtime.
303
+
304
+ ### 1. Generate a dedicated CI key
305
+
306
+ Create an Ed25519 key pair for your CI environment. Do **not** set a passphrase:
307
+
308
+ ```bash
309
+ ssh-keygen -t ed25519 -f ci_key -N "" -C "ci"
310
+ ```
311
+
312
+ This produces two files: `ci_key` (private) and `ci_key.pub` (public).
313
+
314
+ ### 2. Add the key and grant access
315
+
316
+ Register the public key in the project and grant it access to the environments CI needs:
317
+
318
+ ```bash
319
+ dotenc key add ci --from-ssh ./ci_key
320
+ dotenc auth grant test ci
321
+ dotenc auth grant production ci
322
+ git add .
323
+ git commit -m "Add CI key and grant access to test and production"
324
+ git push
325
+ ```
326
+
327
+ ### 3. Set the private key in your CI provider
328
+
329
+ Copy the **entire** contents of the private key file and store it as a secret environment variable named `DOTENC_PRIVATE_KEY` in your CI provider (GitHub Actions, GitLab CI, CircleCI, etc.):
330
+
331
+ ```bash
332
+ cat ci_key
333
+ ```
334
+
335
+ ```
336
+ -----BEGIN OPENSSH PRIVATE KEY-----
337
+ b3BlbnNzaC1rZXktdjEAAAAABG5vbm...
338
+ -----END OPENSSH PRIVATE KEY-----
339
+ ```
340
+
341
+ Paste the full output — including the `BEGIN` and `END` lines — as the value of `DOTENC_PRIVATE_KEY`.
342
+
343
+ Once stored, delete the local private key file:
344
+
345
+ ```bash
346
+ rm ci_key
347
+ ```
348
+
349
+ The public key (`ci_key.pub`) can also be deleted — it's already tracked inside `.dotenc/ci.pub`.
350
+
351
+ ### 4. Use dotenc in your CI pipeline
352
+
353
+ With `DOTENC_PRIVATE_KEY` set, dotenc will automatically pick up the key. No `~/.ssh` directory required:
354
+
355
+ ```bash
356
+ dotenc run -e test npm test
357
+ dotenc run -e production node app.js
358
+ ```
359
+
360
+ ### GitHub Actions example
361
+
362
+ ```yaml
363
+ jobs:
364
+ test:
365
+ runs-on: ubuntu-latest
366
+ steps:
367
+ - uses: actions/checkout@v6
368
+ - uses: actions/setup-node@v6
369
+ with:
370
+ node-version: 24
371
+ - run: npm ci
372
+ - run: npm install -g @dotenc/cli
373
+ - run: dotenc run -e test npm test
374
+ env:
375
+ DOTENC_PRIVATE_KEY: ${{ secrets.DOTENC_PRIVATE_KEY }}
376
+ ```
377
+
378
+ ## Key Management
379
+
380
+ dotenc keeps key management minimal by design. Your SSH keys are your identity - dotenc just uses them.
381
+
382
+ > **Private keys** stay in `~/.ssh/` where they belong. They are never copied or moved.
383
+ > **Public keys** are stored in your project's `.dotenc/` folder, derived from the corresponding private keys.
384
+
385
+ ## Supported Key Types
386
+
387
+ dotenc supports the following SSH key types:
388
+
389
+ - Ed25519
390
+ - RSA (2048-bit or larger)
391
+
392
+ These types are widely supported and provide strong security guarantees.
393
+
394
+ > **Note:** Passphrase-protected SSH keys are not currently supported. dotenc needs to read your private key directly, and it cannot prompt for or decrypt passphrases. If all your keys are passphrase-protected, you can generate a dedicated key without a passphrase:
395
+ >
396
+ > ```bash
397
+ > ssh-keygen -t ed25519 -N ""
398
+ > ```
399
+
400
+ ### Adding a public key
401
+
402
+ ```bash
403
+ dotenc key add [name] [--from-ssh <path>] [-f, --from-file <file>] [-s, --from-string <pem_string>]
404
+ ```
405
+
406
+ Adds a public key into the project (`.dotenc/<name>.pub`).
407
+
408
+ - `--from-ssh <path>` — Derive the public key from an SSH key file (private or public). Supports both Ed25519 and RSA keys.
409
+ - `-f, --from-file <file>` — Read a public (or private) key from a PEM file.
410
+ - `-s, --from-string <pem_string>` — Use a PEM string directly.
411
+ - No arguments — Interactive mode: choose from your SSH keys or paste a PEM public key.
412
+
413
+ ### Listing public keys
414
+
415
+ ```bash
416
+ dotenc key list
417
+ ```
418
+
419
+ Lists all public keys in the project, showing each key's name and algorithm.
420
+
421
+ ### Removing a public key
422
+
423
+ ```bash
424
+ dotenc key remove [name]
425
+ ```
426
+
427
+ Removes a public key from the project, automatically revoking it from every environment.
428
+
429
+ ## Tips
91
430
 
92
431
  For convenience, you can setup your `package.json` file like this:
432
+
93
433
  ```jsonc
94
434
  // ...
95
435
  "scripts": {
96
- "dev": "dotenc run -e development tsx src/app.ts",
436
+ "dev": "dotenc dev tsx src/app.ts",
97
437
  "start": "dotenc run -e production node dist/app.js",
98
438
  "test": "dotenc run -e test vitest"
99
439
  }
@@ -106,20 +446,35 @@ Alternatively, the `DOTENC_ENV` variable can be used to set the environment, so
106
446
  dotenc run node app.js
107
447
  ```
108
448
 
109
- Also, if a key is not present in your machine, you can use the `DOTENC_KEY` variable to decrypt an environment:
449
+ > **Note:** `dotenc textconv` is an internal command used by the git diff driver. It is set up automatically during `dotenc init` and allows `git diff` to show decrypted content of `.env.*.enc` files.
110
450
 
111
- ```bash
112
- DOTENC_KEY=<prod_key> dotenc run -e production node app.js
113
- ```
451
+ ## How dotenc compares
114
452
 
115
- This can be useful for CI and automated platforms like Netlify and Vercel. Just export your keys and set the `DOTENC_KEY` variable in each environment.
453
+ dotenc is a Git-native encryption layer designed for teams who want encrypted environment files committed alongside their code.
454
+ It does not aim to replace centralized secret managers like Vault or Doppler — it serves a different operational model.
116
455
 
117
- The `DOTENC_KEY` variable also works with multiple environments:
456
+ | Capability | dotenc | SOPS (+ age) | Vault | Doppler |
457
+ |-------------|---------|--------------|--------|----------|
458
+ | Git-native encrypted files | ✅ | ✅ | ❌ | ❌ |
459
+ | Uses existing SSH identity | ✅ | ❌ (age / PGP) | ❌ | ❌ |
460
+ | No external service required | ✅ | ✅ | ❌ | ❌ |
461
+ | Environments versioned with code | ✅ | ✅ | ❌ | ❌ |
462
+ | Centralized runtime secret API | ❌ | ❌ | ✅ | ✅ |
463
+ | Dynamic / short-lived secrets | ❌ | ❌ | ✅ | ❌ |
464
+ | Built-in org policy engine | ❌ | ❌ | ✅ | ✅ |
465
+ | Requires running infrastructure | ❌ | ❌ | ✅ | ❌ |
118
466
 
119
- ```bash
120
- DOTENC_KEY=<base_key>,<prod_key> dotenc run -e base,production node app.js
121
- ```
467
+ ## When NOT to use dotenc
468
+
469
+ - If you require centralized policy enforcement
470
+ - If your compliance mandates HSM-backed key storage
471
+ - If you need runtime secret injection via remote API
122
472
 
123
473
  ## License
124
474
 
125
- MIT
475
+ [MIT](LICENSE)
476
+
477
+ [npm-image]: https://img.shields.io/npm/v/@dotenc/cli.svg
478
+ [license-image]: https://img.shields.io/github/license/ivanfilhoz/dotenc.svg
479
+ [downloads-image]: https://img.shields.io/npm/dm/@dotenc/cli.svg
480
+ [npm-url]: https://npmjs.org/package/@dotenc/cli