KB-6B87

dot-iu-cutter v0.4 — Credential Risk & Rollback Plan

6 min read Revision 1
dot-iu-cutterv0.4credential-designrisk-rollbackdieu44

dot-iu-cutter v0.4 — Credential Risk & Rollback Plan

document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-credential-design/dot-iu-cutter-v0.4-credential-risk-and-rollback-plan-2026-05-16.md
revision: r1
date_authored: 2026-05-17
cycle_date_label: 2026-05-16
author: Agent (Claude Code CLI, Opus 4.7 1M)
phase: v0.4 — credential-cycle DESIGN (risk + rollback)
status: design_only_pending_gpt_review

⛔ DESIGN ONLY. Nothing here is executed. The rollback procedure is a TARGET runbook for the SEPARATE, GPT-gated credential execution cycle.


§1 — Risk Classification

this_design_cycle: NONE-to-production. Output = 8 KB documents. Zero DB /
  role / secret / .env / Directus / RLS / deploy touch. Irreversible-action
  risk = none.
future_credential_EXECUTION cycle (assessed for routing, not run here):
  class: STANDARD (consistent with v0.2 P0-2 / v0.3 read-obs ratings).
  basis_for_STANDARD_not_HIGH:
    - operates in an EMPTY schema (all 12 tables 0 rows — v0.2/v0.3
      inventory); no business data at risk;
    - creates only 2 LOGIN roles + a bounded ENUMERATED grant set; no DDL
      on data objects, no superuser, no CREATEROLE/DB, no BYPASSRLS, no RLS,
      no trigger/CHECK/DEFAULT;
    - fully reversible (REVOKE + DROP ROLE; roles memberless & own nothing);
    - preceded by a mandatory isolated dry-run PASS + GPT review +
      command-review (blockers B-1..B-6).
  why_not_LOW: it introduces WRITE-CAPABLE production identities for the
    first time in the cutter programme — a real privilege increase, hence
    STANDARD with mandatory dry-run + command-review gating.
residual_risks_to_carry:
  R-1 secret leakage → mitigated by SC-5 redaction + process isolation +
      separate keys (secret-custody doc).
  R-2 over-grant drift → mitigated by exact catalog verification (dry-run
      D-4) + schema-qualified/structural assertions (P0-6/P0-5 lesson).
  R-3 SoD erosion via verify→cut_change_set INSERT (CD-8/CD-10) → flagged,
      GPT-decided, append-only/forward-only constrained.
  R-4 column-scoped UPDATE cannot enforce write-once on superseded_by →
      stays a code invariant (test-proven in skeleton); documented.
  R-5 single shared dot_pair_signature table → lane separation is
      code/crypto only (CD-11); accepted, no DDL split in v0.4.

§2 — Rollback Principles

- rollback NEVER touches a base table, a view, cutter_ro, Directus, or any
  data — credentials rollback is a ROLE/GRANT-only operation.
- NO CASCADE anywhere (no DROP … CASCADE, no REVOKE … CASCADE) — explicit,
  enumerated, reversible steps only (carries the v0.2/v0.3 no-CASCADE rule).
- rollback is the EXACT inverse of the enumerated grant set — never a
  blanket REVOKE ALL that could catch unintended privileges.
- every rollback step is GATED (pre-condition asserted before it runs).

§3 — Rollback Procedure (target; gated; not executed)

RB-0 GATE: confirm scope = credential objects only; snapshot catalog
     (roles, grants, memberships) before any change.
RB-1 e-stop first if needed: `ALTER ROLE cutter_exec NOLOGIN` /
     `ALTER ROLE cutter_verify NOLOGIN` (halts auth without privilege/role
     change; fully reversible) — fastest containment.
RB-2 terminate live backends for the writer roles
     (pg_terminate_backend on matching pg_stat_activity rows) so REVOKE/
     DROP is not blocked by an active session.
RB-3 REVOKE the enumerated grants — the exact inverse of matrix doc §2
     (per-table S/I, the 2 column-scoped UPDATEs, schema USAGE). NO CASCADE.
RB-4 GATE before DROP: assert each role is
     (a) MEMBERLESS — `pg_auth_members` has no row where roleid/member =
         the writer (no one inherits it, it inherits no one), AND
     (b) OWNS NOTHING — `pg_shdepend` / `pg_class`/`pg_namespace` owner
         scan shows 0 objects owned by the role, AND
     (c) holds NO remaining privilege (post-RB-3 catalog clean).
     If ANY of (a)(b)(c) fails → STOP, do NOT drop, escalate (a role that
     owns something or has members must not be force-dropped).
RB-5 only if RB-4 all-pass: `DROP ROLE cutter_exec` / `DROP ROLE
     cutter_verify` (plain DROP, never DROP OWNED / never CASCADE).
RB-6 verify: catalog returns to the pre-credential baseline — no
     cutter_exec/cutter_verify, cutter_ro UNCHANGED (still NOLOGIN, 13
     view/schema grants, 0 base-table grant), 12 tables/12 views intact,
     prod sysid unchanged, 0 rows anywhere.
RB-7 secret rollback: the corresponding .env keys (if they were created in
     the execution cycle) are removed/zeroised by the same authorized
     operator; no secret value is logged. (In THIS design cycle nothing
     exists to remove.)
partial_state_rule: if execution aborted mid-grant, RB-3..RB-6 still apply
     (REVOKE is idempotent per object; DROP gated by RB-4).

§4 — Explicit Rollback Gates (summary)

G-RB-1 scope = credentials only (no data/table/view/cutter_ro/Directus).
G-RB-2 no CASCADE on any REVOKE or DROP.
G-RB-3 DROP ROLE only if memberless AND owns nothing AND no privilege left.
G-RB-4 cutter_ro state byte-identical before and after (v0.3 inventory §4).
G-RB-5 prod sysid identical before and after; 0 rows unchanged.
G-RB-6 schema-qualified / structural catalog assertions (no bare-string
       false-negative — feedback memory pg_get_constraintdef lesson).

§5 — Non-Scope

NOT here: any REVOKE, any DROP ROLE, any ALTER ROLE, any .env change, any
connection. Target runbook specification only; executed nowhere.

End of credential risk & rollback plan (design only; nothing executed).

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.4-credential-design/dot-iu-cutter-v0.4-credential-risk-and-rollback-plan-2026-05-16.md