envpkt 0.13.3 → 0.13.5
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 +54 -2
- package/dist/cli.js +934 -778
- package/dist/index.d.ts +18 -1
- package/dist/index.js +61 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -181,6 +181,15 @@ const result = boot() // decrypts sealed values, injects into process.env
|
|
|
181
181
|
|
|
182
182
|
Mixed mode is supported — sealed values take priority, with fnox as fallback for keys without `encrypted_value`.
|
|
183
183
|
|
|
184
|
+
### Where it injects: self-launched vs serverless
|
|
185
|
+
|
|
186
|
+
Whether envpkt can replace a cloud secret store depends on one thing: **do you control how the process starts?**
|
|
187
|
+
|
|
188
|
+
- **You launch it** (server, container, VM, k8s, systemd) → `envpkt exec -- yourapp` or `boot()` injects the decrypted values straight into the process environment. No cloud secret store needed: the sealed `envpkt.toml` ships with the app, and only the age key has to reach the runtime (N secrets collapse to 1 key).
|
|
189
|
+
- **A platform launches it** (Cloudflare Workers, AWS Lambda, Vercel) → you don't own the launch, and the `age` CLI can't run inside the per-request isolate, so the platform's secret store is unavoidable. envpkt becomes the source of truth that populates and audits that store — not the injector.
|
|
190
|
+
|
|
191
|
+
> Rule of thumb: **own the launch → `exec`/`boot`, no store. Platform owns the launch → store required, envpkt feeds and audits it.** Full details: [Runtime injection guide](https://envpkt.dev/guides/runtime-injection/).
|
|
192
|
+
|
|
184
193
|
## GitHub Actions
|
|
185
194
|
|
|
186
195
|
A composite action resolves the credentials in `envpkt.toml` into the CI job — with secret values masked in the log — so later steps just see them as environment variables:
|
|
@@ -191,7 +200,7 @@ A composite action resolves the credentials in `envpkt.toml` into the CI job —
|
|
|
191
200
|
# Sealed packets are decrypted with the `age` CLI (not preinstalled on runners).
|
|
192
201
|
- run: sudo apt-get update && sudo apt-get install -y age
|
|
193
202
|
|
|
194
|
-
- uses: jordanburke/envpkt@v0
|
|
203
|
+
- uses: jordanburke/envpkt@v0
|
|
195
204
|
with:
|
|
196
205
|
config: ./envpkt.toml
|
|
197
206
|
strict: "true" # fail the build if a credential is expired/unhealthy
|
|
@@ -205,7 +214,36 @@ A composite action resolves the credentials in `envpkt.toml` into the CI job —
|
|
|
205
214
|
|
|
206
215
|
**Inputs:** `config`, `version` (npm version to run, default `latest`), `strict`, `profile`.
|
|
207
216
|
|
|
208
|
-
> Decrypting sealed packets requires the [`age`](https://github.com/FiloSottile/age) CLI on the runner (install it first, as above) — not needed if you only inject plaintext `[env.*]` defaults or resolve via fnox.
|
|
217
|
+
> Decrypting sealed packets requires the [`age`](https://github.com/FiloSottile/age) CLI on the runner (install it first, as above) — not needed if you only inject plaintext `[env.*]` defaults or resolve via fnox. Reference `@v0` for the moving major tag (re-pointed to each `0.x` release), or pin an exact release like `@v0.13.4` for immutability. `@v1` ships when envpkt reaches 1.0. Node is assumed present; add `actions/setup-node` first to pin a version.
|
|
218
|
+
|
|
219
|
+
### Anti-rot CI gate
|
|
220
|
+
|
|
221
|
+
A hand-maintained `envpkt.toml` is documentation, and documentation rots. The fix is a failing build: each `--strict` check exits non-zero so a stale or drifted config blocks the merge. Each gate is **metadata-only** (no secret values) and targets a different failure mode — compose the ones that fit:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# 1. Secret health — runs anywhere, no live env or age key needed.
|
|
225
|
+
# Fails on expired / stale (> lifecycle.stale_warning_days) / missing / missing-metadata.
|
|
226
|
+
envpkt audit --strict # exit 1 = degraded, 2 = critical
|
|
227
|
+
|
|
228
|
+
# 2. Cross-environment parity — keep dev/staging/prod tracking the same keys.
|
|
229
|
+
envpkt diff dev.envpkt.toml prod.envpkt.toml --exit-code
|
|
230
|
+
|
|
231
|
+
# 3. Drift vs the live environment — run where the env is actually populated
|
|
232
|
+
# (a deployed host or a pre-deploy step), NOT a bare CI runner: with no env
|
|
233
|
+
# set, every var reads as "missing" and the gate false-fails.
|
|
234
|
+
envpkt env check --strict # exit 1 on any drift (missing / untracked)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Where each belongs.** `audit --strict` and `diff --exit-code` are environment-independent — drop them in any PR/CI job as a merge gate. `env check --strict` compares the config against the _live_ environment, so it belongs in a pre-deploy step or a host healthcheck, after the env is populated (e.g. `eval "$(envpkt env export)"`), not in a stock CI runner.
|
|
238
|
+
|
|
239
|
+
```yaml
|
|
240
|
+
# PR gate: block merges when the config rots (no secrets, no age key required)
|
|
241
|
+
- uses: jordanburke/envpkt@v0.13.4
|
|
242
|
+
with: { config: ./envpkt.toml, strict: "true" }
|
|
243
|
+
- run: envpkt diff dev.envpkt.toml prod.envpkt.toml --exit-code
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
> Freshness in the sense of "verified live within N days" (a credential that still _authenticates_, not just one that hasn't _expired_ on paper) is a [verification](#) capability reserved for the hosted offering — `--strict` enforces everything checkable offline today.
|
|
209
247
|
|
|
210
248
|
## For agents and fleets
|
|
211
249
|
|
|
@@ -424,6 +462,20 @@ envpkt diff a.toml b.toml --format json # structured diff
|
|
|
424
462
|
envpkt diff a.toml b.toml --exit-code # exit non-zero on any difference (CI drift gate)
|
|
425
463
|
```
|
|
426
464
|
|
|
465
|
+
### `envpkt copy`
|
|
466
|
+
|
|
467
|
+
Copy a secret or env entry from one config to another. For a sealed secret, the value is unsealed with the **source's** age key and resealed for the **destination's** `identity.recipient` automatically — so you can move a credential between configs that use different keys without ever handling the plaintext yourself. Env entries (and secrets with no sealed value) copy as metadata only. The kind (secret vs env) is detected from where the key lives in the source.
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
envpkt copy DATABASE_URL --from prod.envpkt.toml --to staging.envpkt.toml
|
|
471
|
+
envpkt copy DATABASE_URL --from prod.envpkt.toml --to staging.envpkt.toml --as DB_URL # rename on copy
|
|
472
|
+
envpkt copy PORT --to other.envpkt.toml # --from defaults to the resolved config here
|
|
473
|
+
envpkt copy API_KEY --to b.toml --force # overwrite if it already exists in the destination
|
|
474
|
+
envpkt copy API_KEY --to b.toml --dry-run # preview without writing
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
`--from`/`--to` default to the config resolved for the current directory (and must already exist). On copy, `created` is reset to today and `last_rotated_at` is dropped (it's the source's rotation history). Copying a sealed secret needs the source key to unseal and the destination's `identity.recipient` to reseal.
|
|
478
|
+
|
|
427
479
|
### `envpkt exec`
|
|
428
480
|
|
|
429
481
|
Run a pre-flight audit, inject secrets from fnox into the environment, then execute a command.
|