|
1 | 1 | # @cipherstash/cli |
2 | 2 |
|
| 3 | +## 1.0.0-rc.3 |
| 4 | + |
| 5 | +### Minor Changes |
| 6 | + |
| 7 | +- 3a86939: EQL v3 support for the encryption rollout lifecycle (#648). The `stash |
| 8 | +encrypt *` commands (and `@cipherstash/migrate` underneath) now resolve a |
| 9 | + column's EQL version and its encrypted counterpart from the **Postgres domain |
| 10 | + types** — the EQL v3 types are self-describing, so the `<col>_encrypted` |
| 11 | + naming is a convention only, never enforced or relied upon — and follow the |
| 12 | + right lifecycle, no new flags: |
| 13 | + |
| 14 | + - **`encrypt backfill`** works on v3 columns unchanged (the engine was always |
| 15 | + version-agnostic; pass an `EncryptionV3` client and real v3 envelopes land |
| 16 | + in the concrete `eql_v3_*` domain column — verified live against a real |
| 17 | + database, including the domain CHECK and a decrypt round-trip). The |
| 18 | + manifest records the detected version, the encrypted column's name, and the |
| 19 | + v3 target phase, and the command prints v3-appropriate next steps. |
| 20 | + - **`encrypt cutover`** on a backfilled v3 column reports "not applicable" |
| 21 | + (exit 0) with guidance: v3 has no rename cut-over — the application |
| 22 | + switches to the encrypted column by name. Before backfill completes it |
| 23 | + exits 1 and says to finish the backfill instead of instructing the switch. |
| 24 | + On a database with no `eql_v2_configuration` table (a v3-only install) the |
| 25 | + v2 path now explains that instead of surfacing a raw Postgres error. |
| 26 | + - **`encrypt drop`** is version-aware: v3 runs from the `backfilled` phase, |
| 27 | + **verifies live coverage** (refuses to generate the migration while any row |
| 28 | + still has the plaintext set and the encrypted column NULL — the |
| 29 | + `countUnencrypted` check), and drops the ORIGINAL plaintext column (there |
| 30 | + is no `<col>_plaintext` under v3); v2 behaviour is unchanged. The generated |
| 31 | + v3 migration **re-verifies coverage at apply time** — it locks the table, |
| 32 | + re-counts, and aborts without dropping if plaintext-only rows appeared |
| 33 | + after generation. And because dropping is the one irreversible step, it |
| 34 | + requires a positively asserted plaintext↔ciphertext pairing (the |
| 35 | + manifest's recorded `encryptedColumn` or the naming convention): a match |
| 36 | + found only by being the table's sole EQL column is refused with |
| 37 | + instructions, and an ambiguous table (several EQL columns, none |
| 38 | + identifiable) fails closed listing the candidates — as does `cutover`. |
| 39 | + - **`encrypt status`** classifies each column from the observed domain type |
| 40 | + (manifest as fallback), shows `v3` in the EQL column, and no longer raises |
| 41 | + the v2-only `not-registered` / `plaintext-col-missing` drift flags for v3 |
| 42 | + columns. `stash status`'s quest ladder and the `stash init` agent handoff |
| 43 | + prompt teach the version-appropriate next step (no more "run cutover" on |
| 44 | + v3 columns). |
| 45 | + - New `@cipherstash/migrate` exports: `classifyEqlDomain`, |
| 46 | + `resolveEncryptedColumn`, `pickEncryptedColumn`, `listEncryptedColumns` |
| 47 | + (domain-type resolution — case-exact for quoted/mixed-case table names), |
| 48 | + `countEncrypted` / `countUnencrypted` (coverage counts), and manifest |
| 49 | + `eqlVersion` + `encryptedColumn` fields. `EqlVersion` is numeric (`2 | 3`), |
| 50 | + matching the manifest and the installer. Resolved columns carry `via: |
| 51 | +'hint' | 'convention' | 'sole'` so callers can tell a positively asserted |
| 52 | + pairing from a by-elimination guess. |
| 53 | + - Fixed: `encrypt cutover`/`encrypt drop` precondition failures now actually |
| 54 | + exit 1 — the early-return guards previously skipped the exit-code path |
| 55 | + entirely, so failed preconditions exited 0. (This also applies to v2 |
| 56 | + preconditions: scripted pipelines that relied on the erroneous exit 0 will |
| 57 | + now see the documented exit 1.) |
| 58 | + |
| 59 | + The `stash-cli` and `stash-encryption` skills and the `@cipherstash/migrate` |
| 60 | + README document the two lifecycles (v2: backfill → cutover → drop; |
| 61 | + v3: backfill → switch-by-name → drop). |
| 62 | + |
| 63 | +### Patch Changes |
| 64 | + |
| 65 | +- 8b2551a: Fix "Failed to load native binding" on project-local installs of the CLI/SDK |
| 66 | + (npm). `@cipherstash/auth` was pinned at 0.41.0 while the six |
| 67 | + `@cipherstash/auth-*` platform bindings declared in stack/stash/wizard's |
| 68 | + optionalDependencies were pinned at 0.42.0. Because auth pins its bindings as |
| 69 | + exact-version optional peer dependencies, the skew made npm nest per-consumer |
| 70 | + binding copies that the hoisted `auth` package could not resolve — any command |
| 71 | + or import touching auth then died at startup. All seven packages now move in |
| 72 | + lockstep at 0.42.0, Dependabot is barred from bumping any of them |
| 73 | + independently, and a supply-chain CI test fails on any future skew. |
| 74 | +- Updated dependencies [3a86939] |
| 75 | + - @cipherstash/migrate@1.0.0-rc.1 |
| 76 | + |
3 | 77 | ## 1.0.0-rc.2 |
4 | 78 |
|
5 | 79 | ### Patch Changes |
|
0 commit comments