KB-5376

dot-iu-cutter v0.4 — Secret Custody Design

8 min read Revision 1
dot-iu-cutterv0.4credential-designsecret-custodydieu44

dot-iu-cutter v0.4 — Secret Custody Design

document_path: knowledge/dev/laws/dieu44-trien-khai/v0.4-credential-design/dot-iu-cutter-v0.4-secret-custody-design-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 (secret custody)
status: design_only_pending_gpt_review

⛔ DESIGN ONLY. NO secret is created, read, printed, or stored. NO .env is read or edited. This document specifies WHERE and HOW the future secrets will live — it contains NO secret value and names NO key value.


recommended: VPS-side env file — the established project convention already
  used for Agent Data / Directus credentials at /opt/incomex/docker/.env
  (cf. project memory: "Agent Data cloud API key stored on VPS at
  /opt/incomex/docker/.env"; "Cloud credentials in .env.local"). Reuse of
  this proven pattern minimizes new surface and matches strategy SC-2.
  Two NEW, SEPARATE keys (names TBD in the execution cycle, illustrative):
    CUTTER_EXEC_PG_*    — cutter_exec connection secret
    CUTTER_VERIFY_PG_*  — cutter_verify connection secret
  NEVER the directus / workflow_admin / postgres password; never shared
  between the two writers (SC-1, SC-3).
alternative (CD-4): GCP Secret Manager, IF available to this project. Not
  probed in this design cycle (would be infra interaction). If chosen, a
  later AUTHORIZED step performs a read-only availability check
  (`gcloud secrets list` equivalent) BEFORE any decision is locked.
  Trade-off: GCP SM = central rotation/audit/IAM but new dependency &
  bootstrap; VPS .env = zero new dependency, matches every prior cycle,
  weaker native rotation/audit (compensated by §5/§6 below).
recommendation: VPS .env for v0.4 (OD-CR-1 confirmed-pending-GPT); GCP SM
  reconsidered only if GPT directs and availability is later verified.
not_in_scope_anywhere: storing any secret in the repo, in Agent Data, in
  Directus, in this or any KB document, in logs, in CLI output.

§2 — Process Isolation (backs DB-level SoD)

- cutter_exec secret and cutter_verify secret are SEPARATE keys. The
  process running the executor lane is configured with ONLY the exec key;
  the verifier-lane process with ONLY the verify key. Neither can read the
  other's secret → process isolation reinforces the distinct-DB-role SoD
  (strategy SC-3; credential model §3 layer (b)).
- the cutter-agent code already takes NO env/secret at all (@689e53e:
  no os.environ, no DSN); the real DB adapter (separate future cycle) will
  receive its principal's secret via injected config, never by reading a
  shared global env in-process.
- harness/log redaction is a CODE-cycle requirement, recorded here as a
  binding constraint (SC-5): the agent NEVER prints, logs, or echoes a
  writer secret or DSN; test_security_boundaries already asserts no
  secret/DSN regex in CLI output for the skeleton — the real adapter must
  preserve this.

§3 — No Secret Creation Now (hard)

- NO password minted. NO key generated. NO .env line added or read.
- NO `ALTER ROLE … PASSWORD`. NO connection string assembled.
- secret minting happens ONLY in the dedicated, separately-authorized,
  GPT-gated credential EXECUTION cycle, AFTER the isolated dry-run PASS.

§4 — No Secret Printing (hard)

- this document, the report, and all design docs contain NO secret value,
  NO key name's value, NO DSN.
- the future adapter and CLI must redact secrets in every code path
  (errors, logs, tracebacks, demo output). Verification = grep proof in the
  real-adapter code-review cycle (same discipline as skeleton §5C).

§5 — Rotation Plan (target; not executed)

- passwords are designed ROTATABLE: a future AUTHORIZED op does
  `ALTER ROLE cutter_exec PASSWORD …` / `ALTER ROLE cutter_verify PASSWORD …`
  then updates the corresponding .env key, then restarts only the affected
  lane process.
- rotation is per-principal and INDEPENDENT (rotating exec must not require
  touching verify's secret).
- no rotation SCHEDULE is fixed here (operational decision for the
  execution/run cycle); design only mandates that rotation be possible
  without DDL and without downtime of the unaffected lane.
- on substrate = GCP SM: rotation = add new secret version + redeploy lane
  config; old version disabled after cutover.

§6 — Revocation, Audit Trail, Emergency Disable

revocation (target; not executed):
  - immediate disable WITHOUT dropping the role: `ALTER ROLE <writer>
    NOLOGIN` (kills new connections; existing ones terminated by
    pg_terminate_backend) — fast, reversible, no privilege/grant change.
  - privilege revocation: `REVOKE … ` of the enumerated grants (matrix doc
    §2) — exact inverse of the grant set, no CASCADE (see rollback doc).
  - role drop: only if memberless and owns nothing (rollback doc gates).
audit_trail:
  - PG-side: enable log_connections / log_disconnections for the writer
    roles (target; an execution-cycle setting, named here as a requirement)
    so every cutter_exec / cutter_verify auth is logged.
  - app-side: the decision_backlog_history append-only ledger already
    records actor + reason + timestamp on every status transition
    (ledger.transition_status), giving a tamper-evident write trail keyed
    to the principal/lane independent of PG logs.
  - the DOT-991/DOT-992 dot_pair_signature chain provides cryptographic
    attribution of every cut/verify to its lane (once real signing lands —
    separate deferred cycle; v0.4 Stub is non-crypto, is_production=False).
emergency_disable (e-stop):
  - single fastest action: `ALTER ROLE cutter_exec NOLOGIN` and/or
    `ALTER ROLE cutter_verify NOLOGIN` → cutter-agent cannot authenticate
    → all further writes halt; read layer (cutter_ro) and Directus
    UNAFFECTED. No grant/role/data change; fully reversible by
    `ALTER ROLE … LOGIN`.
  - this is a target runbook entry, NOT executed or installed in this cycle.

§7 — Open Decisions (secret-specific; for GPT)

CD-3  SECURITY DEFINER wrapper functions (writers call functions, not
      tables) vs direct table grants. RECOMMEND direct grants for v0.4:
      auditable, no function-owner privilege-escalation surface, simpler
      dry-run. Revisit if real-adapter design needs it.
CD-4  secret substrate: VPS /opt/incomex/docker/.env (RECOMMENDED) vs GCP
      Secret Manager (needs later authorized availability check).
CD-5  auth method: scram-sha-256 PASSWORD (RECOMMENDED for v0.4) vs
      client-certificate auth (stronger, more bootstrap; DEFER).
CD-12 whether log_connections for writer roles is enabled at execution
      time (RECOMMEND yes).

§8 — Non-Scope

NOT here: secret mint/read/print, .env read/edit, ALTER ROLE, connection,
  GCP probe, log config change. Specification of custody intent only.

End of secret custody design (design only; no secret created/read/printed).

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