Skip to content
This repository was archived by the owner on Sep 2, 2026. It is now read-only.
This repository was archived by the owner on Sep 2, 2026. It is now read-only.

v3 lifecycle must never lose encrypted data #360

Open

Description

@coderdan

Decision

EQL v3 follows the EQL v2 persistence boundary:

  • Data-bearing domains live in public and are durable.
  • eql_v3 and eql_v3_internal contain disposable machinery and may be dropped with CASCADE.
  • Install, uninstall, and reinstall must never remove an application table, encrypted column, or stored encrypted value.
  • Functional indexes are derived state and are handled separately by Make EQL reinstall safe: rebuild indexes and reject unsafe dependencies stack#918.

We explicitly rejected object-by-object patch/minor upgrade scripts: generating and maintaining safe in-place DDL across PostgreSQL object types is brittle and creates a more dangerous lifecycle than reinstalling disposable machinery.

Remaining work

  • Run the SQLx lifecycle regression across every installed public.eql_v3_* data-bearing domain using real encrypted fixtures.
  • Prove table, column type, row count, and stored JSONB are unchanged after uninstall and reinstall on every supported PostgreSQL version.
  • Assert shipped lifecycle artifacts never explicitly drop the durable public domains.
  • Close this issue when those tests pass in CI.

Related work

Activity

  1. self-assigned this
    on Jul 4, 2026
  2. coderdan commented on Aug 19, 2026

    @coderdan
    ContributorAuthor

    Reopening — as far as I can tell the proposal here never shipped: eql-3.0.5 still releases only cipherstash-encrypt.sql + the uninstaller, no versioned upgrade scripts, and the bundle still opens with DROP SCHEMA IF EXISTS eql_v3 CASCADE. (If this was closed in favour of internal tracking, feel free to re-close with a pointer.)

    Two updates from the consumer side (cipherstash/stack) since this was written:

    1. The data-destruction half is fixed by placement — the column domains now live in public and survive the schema drop. What remains is exactly the index-bearing/pure-function half of the taxonomy above: every functional index over an eql_v3.* extractor (plus any constraint or RLS policy calling those functions) is cascade-dropped on every upgrade, silently — queries fall back to sequential scans without erroring, and no migration runner recreates indexes it already applied. Details and downstream mitigation: Make EQL reinstall safe: rebuild indexes and reject unsafe dependencies stack#918.

    2. Stack is adding a capture-and-restore workaround (stash eql upgrade snapshots pg_get_indexdef() for dependent indexes before the drop and re-issues them after) — but that's a workaround, not the fix. Most patch releases touch a handful of pure functions; per this issue's own taxonomy they're CREATE OR REPLACE-able and would preserve dependent indexes with no rebuild at all. At 10M rows the difference is hours of index rebuild vs. zero.

    The minimal slice that would remove the standing footgun for minor/patch releases is proposal item 2: auto-emitted upgrade-<from>-to-<to>.sql artifacts (CREATE OR REPLACE + additive CREATEs, refusing to auto-generate on domain/opclass changes), plus the item-3 CI gate proving upgrade ≡ fresh install.

  3. changed the title [-]v3: no safe patch/minor upgrade path — uninstall is destructive for domain columns; ship versioned upgrade scripts[/-] [+]v3 lifecycle must never lose encrypted data[/+] on Aug 31, 2026
  4. tobyhede commented on Aug 31, 2026

    @tobyhede
    Contributor

    This work moved with EQL into the cipherstash/stack monorepo. Active lifecycle-safety tracking is now cipherstash/stack#959; derived-index and dependency reconstruction is cipherstash/stack#918. This upstream repository is historical provenance only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions