diff --git a/README.md b/README.md index f7f03db..fb1bb4f 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,28 @@ People end up sharing secrets over Slack, email, or sticky notes. When a key cha `secrets` encrypts your secret files and stores them in a separate, private git repository. Only someone with the encryption key can read them. -```diagram -Your project (e.g. ~/myapp/) Your secrets store (~/.secrets/) -┌──────────────────────────┐ ┌──────────────────────────┐ -│ .env (plaintext)│──encrypt─▶│ myapp/.env.age (encrypted)│──sync──▶ GitHub (private) -│ .env.staging (plaintext)│ │ myapp/.env.staging.age │ -│ .dev.vars (plaintext)│ │ key.txt (never uploaded) │ -└──────────────────────────┘ └──────────────────────────┘ +```mermaid +flowchart TD + subgraph project["Your project (~/myapp/)"] + direction TB + p1[".env (plaintext)"] + p2[".env.staging (plaintext)"] + p3[".dev.vars (plaintext)"] + end + + subgraph store["Your secrets store (~/.secrets/)"] + direction TB + s1["myapp/.env.age (encrypted)"] + s2["myapp/.env.staging.age"] + k["key.txt (never uploaded)"] + end + + gh["GitHub (private)"] + + project -->|secrets push
encrypt| store + store -->|git push| gh + gh -->|git pull| store + store -->|secrets pull
decrypt| project ``` - **Encrypted at rest** — files are encrypted with [age](https://github.com/FiloSottile/age), a modern encryption tool. Without the key, the files are unreadable. @@ -160,18 +175,41 @@ When you run `secrets push` or `secrets pull` without specifying a project name, You can also specify a name explicitly: `secrets push myapp`. -### Minimizing plaintext exposure +### secrets run -Every second that plaintext secret files sit on disk is a window for a compromised tool or dependency to read them. `secrets run` shrinks that window to only while your command is running: +`secrets run` is a **pull → run → clear** pipeline: it runs `secrets pull` to decrypt the latest files into your project, executes your command, then runs `secrets clear` when that command finishes. Plaintext `.env` / `.dev.vars` files exist only while your command is running. -```bash -secrets run npm start # .env exists only while dev server is up -secrets run wrangler deploy # .dev.vars exists only during deploy +That matters because anything on disk can be read by other processes. `secrets run` keeps that window as small as possible—useful for dev servers, deploys, and one-off scripts. + +```mermaid +flowchart TD + subgraph run["secrets run"] + direction TB + A[secrets pull] --> B["Your command"] + B --> C[secrets clear] + end ``` -When the command exits — whether normally, from an error, or from Ctrl-C — the plaintext files are automatically deleted. +`secrets clear` is hooked to **shell exit**, so it runs after **success**, **non-zero exit**, or **Ctrl-C** (SIGINT). -This works in `package.json` scripts too, so your whole team gets the protection automatically: +**Syntax** + +```bash +secrets run [args...] +secrets run -w [args...] # monorepo: all workspaces (needs jq) +secrets run -- # if the command starts with - +``` + +Use **`--`** when the program you are running begins with a dash so it is not parsed as a `secrets` flag. + +**Examples** + +```bash +secrets run npm start # .env only while the dev server runs +secrets run wrangler deploy # .dev.vars only during deploy +``` + +**`package.json` scripts** so the whole team gets the same behavior by default: ```json { @@ -182,7 +220,9 @@ This works in `package.json` scripts too, so your whole team gets the protection } ``` -Now `npm run dev` pulls secrets, starts the dev server, and clears secrets when you stop it. +Stopping the dev server (or any failing command) ends the process; the `EXIT` trap clears secrets afterward. + +If you prefer to keep decrypted files on disk for a long editing session, use `secrets pull` and `secrets clear` manually instead. ### Monorepo support diff --git a/secrets b/secrets index 0b24ce2..a1d92c8 100755 --- a/secrets +++ b/secrets @@ -1,6 +1,8 @@ #!/usr/bin/env bash set -euo pipefail +# SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 + # secrets — encrypted env file sync between machines # Uses age key-file encryption + a private git repo.