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
.envis read or edited. This document specifies WHERE and HOW the future secrets will live — it contains NO secret value and names NO key value.
§1 — Substrate (recommended) and the GCP Alternative (CD-4)
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).