@jondotsoy/envs 0.1.4 → 0.1.5-demo.0
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 +2 -0
- package/SECURITY.md +31 -1
- package/envs.js +5496 -10
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -29,6 +29,8 @@ Run the commands inside the repo or any of its worktrees. Inside a worktree, `.e
|
|
|
29
29
|
| `envs push` | Writes `values.yml` to the `.env` of each worktree. Updates existing variables in place, appends new ones at the end, and keeps comments and variables that are not in `values.yml`. |
|
|
30
30
|
| `envs lint` | Checks security and prints a warning for each problem. Exits with code 1 if there is any (useful in CI). See below. |
|
|
31
31
|
| `envs edit` | Runs `pull`, opens `values.yml` with `code -w` and, when the editor closes, runs `push`. If the editor fails, it does not `push`. |
|
|
32
|
+
| `envs share` | Shares the `main` profile over a P2P link (`envs://…`). Shows a warning and requires `y`/`yes`. Options: `--max-peers N`, `--ttl MINUTES`, `--peer-server URL`. See [docs/sharing/p2p.md](docs/sharing/p2p.md). |
|
|
33
|
+
| `envs receive <link>` | Fetches the variables behind a sharing link and, after `y`/`yes`, merges them into `values.yml` `defaults`. Existing keys are kept unless you pass `--force`. |
|
|
32
34
|
| `envs help` | Shows the help. |
|
|
33
35
|
|
|
34
36
|
Worktrees are identified by their branch name (or their folder name if they are in detached HEAD). The main repo uses its branch name, for example `main`.
|
package/SECURITY.md
CHANGED
|
@@ -29,12 +29,15 @@ I will reply as soon as possible and we will coordinate the fix and the disclosu
|
|
|
29
29
|
| `envs pull` | `<worktree>/.env` of each worktree | Rewrites `<root>/.envs/values.yml`. The file is serialized again, so YAML comments are lost. |
|
|
30
30
|
| `envs push` | `<root>/.envs/values.yml` | Creates or updates `<worktree>/.env` of each worktree that has values. Updates existing variables in place, appends new ones at the end and keeps the rest of the file. If there are `defaults`, this includes all worktrees. |
|
|
31
31
|
| `envs edit` | Same as `pull` and `push` | Same as `pull` and `push`. It also runs `code -w <root>/.envs/values.yml`. |
|
|
32
|
+
| `envs share` | `<root>/.envs/values.yml` | Creates `<root>/.envs/sharing-envs` (encrypted, mode `0600`) and deletes it when the session ends. Appends to `<root>/.envs/sharing-connections.ndjson` (mode `0600`). |
|
|
33
|
+
| `envs receive` | `<root>/.envs/values.yml` | After an explicit `y`/`yes`, rewrites `<root>/.envs/values.yml` (YAML comments are lost) adding the received variables to `defaults`. |
|
|
32
34
|
|
|
33
35
|
Additionally:
|
|
34
36
|
|
|
35
37
|
- It runs `git rev-parse` and `git worktree list` to locate the root and the worktrees. These are read-only commands.
|
|
36
38
|
- `envs edit` runs the `code` program found in the `PATH`.
|
|
37
|
-
-
|
|
39
|
+
- Only `envs share` and `envs receive` use the network (see [Network: P2P sharing](#network-p2p-sharing)). Every other command makes no network connections.
|
|
40
|
+
- It does not modify other project files, not even your project's `.gitignore`.
|
|
38
41
|
|
|
39
42
|
## Handling secrets
|
|
40
43
|
|
|
@@ -44,6 +47,8 @@ Additionally:
|
|
|
44
47
|
- `envs init` creates `.envs/.gitignore` with `*`, so the `.envs/` folder is not committed to git. Do not remove that file.
|
|
45
48
|
- `envs push` writes the values to the `.env` files of each worktree. Make sure `.env` is in your project's `.gitignore`.
|
|
46
49
|
- Do not share `values.yml` or paste it in issues or logs.
|
|
50
|
+
- `.envs/sharing-envs` is encrypted with a key that exists only in the sharing link, is created with mode `0600`, covered by `.envs/.gitignore`, and is deleted when the session ends (also on `Ctrl+C`).
|
|
51
|
+
- The sharing link contains the secret that decrypts your variables. Treat it as a password.
|
|
47
52
|
|
|
48
53
|
## Console output
|
|
49
54
|
|
|
@@ -53,4 +58,29 @@ Additionally:
|
|
|
53
58
|
- Masking is based on the name only. A secret stored in a variable with an innocuous name (for example `DATABASE_URL` with a password inside) is printed as is.
|
|
54
59
|
- `envs pull` never prints values, only branch names and the number of variables.
|
|
55
60
|
- `envs lint` messages never include the matched value.
|
|
61
|
+
- `envs share` prints the sharing link, which includes the secret. It is printed once, to the terminal only; it is never written to disk or to the audit log. Do not run it in a terminal whose output is recorded.
|
|
62
|
+
- `envs receive` prints the number of variables received, never their names or values.
|
|
56
63
|
- Set `NO_COLOR` to a non-empty value to print the output without colors.
|
|
64
|
+
|
|
65
|
+
## Network: P2P sharing
|
|
66
|
+
|
|
67
|
+
`envs share` and `envs receive` are the only commands that use the network. Full details are in [docs/sharing/p2p.md](docs/sharing/p2p.md); this is what is protected and what is not.
|
|
68
|
+
|
|
69
|
+
**Consent.** `envs share` prints a warning with precautions and does nothing until you type `y` or `yes`. `envs receive` asks the same before it modifies `values.yml`.
|
|
70
|
+
|
|
71
|
+
**What the mechanism protects.**
|
|
72
|
+
|
|
73
|
+
- *Confidentiality of the variables.* They travel in two encrypted layers derived from the link secret with HKDF-SHA512: the `sharing-envs` file (AES-256-GCM) and, on top of the WebRTC channel (DTLS), an authenticated application layer (AES-256-GCM with X25519 forward-secret keys). Whoever relays the traffic (network, PeerJS broker) sees only ciphertext.
|
|
74
|
+
- *Authentication of both peers.* A handshake authenticated with HMAC-SHA512 over the secret proves that each side knows the link. A broker or network attacker that rewrites the signaling data cannot forge it, so it cannot sit in the middle.
|
|
75
|
+
- *Replays and tampering.* Frames are numbered, bound to the session and direction, and rejected if they repeat, arrive out of order or are modified.
|
|
76
|
+
- *Exposure window.* A session is single use by default (`--max-peers`), expires after 10 minutes (`--ttl`), closes after 3 failed authentications, and removes `sharing-envs` when it ends.
|
|
77
|
+
- *Auditing.* Every connection attempt is appended to `.envs/sharing-connections.ndjson` (one JSON object per line: time, session hash, event, a random peer id, the remote IP when the WebRTC backend reports it, and counters). It never contains the secret, the link, or variable names or values.
|
|
78
|
+
|
|
79
|
+
**What it does not protect.**
|
|
80
|
+
|
|
81
|
+
- *The link.* Anyone who obtains it before it expires or is used can read your `main` variables. Send it over a private channel.
|
|
82
|
+
- *Metadata.* All client/server communication goes through [PeerJS](https://peerjs.com/). The PeerJS broker (PeerJS Cloud by default, or your own with `--peer-server`) sees the random peer ids, when a session exists and the IPs that connect to it. The WebRTC session description also passes through it in clear text, so it exposes the ICE candidates (IP addresses). Google's STUN servers (`stun*.l.google.com:19302`) see your public IP. Neither sees the payload.
|
|
83
|
+
- *Availability.* The public broker is a free service with no guarantees. There is no TURN relay, so peers behind symmetric NAT or CGNAT may be unable to connect.
|
|
84
|
+
- *Endpoints.* Once received, variables are plain text in `values.yml` and `.env` with the protections described above.
|
|
85
|
+
|
|
86
|
+
The `remote` field of the audit log is personal data (an IP address). The file stays on your machine, but treat it accordingly if you share or archive it.
|