O7 postdeploy live dry-run (Contabo) — 03-readonly-access-survey
O7 Report 03 — Read-only DB access survey
- macro:
v0.6-o7-postdeploy-live-dryrun-contabo - gate: G2
- result: PASS (read-only path established; one documented limitation)
Read-only access path (existing, discovered — no secret minted)
- Postgres: container
postgres(postgres:16), exposed127.0.0.1:5432, databasedirectus. - Credentials:
/opt/incomex/secrets/.env.production(Đ33 §14 SSOT) keysPGHOST PGPORT PG_DB_MAIN PG_USER_RO PG_PASSWORD_RO PG_USER_RW PG_PASSWORD_RW. The runner reads this file at runtime; no secret is printed or hardcoded. PG_USER_ROresolves to PostgreSQL rolecontext_pack_readonly— the same role the existingdot-context-pack-*tooling uses for cross-DB reads. This is the canonical existing read-only path.
Read-only identity proof (orchestrator read_only_role_status())
The psycopg2 connection is opened as context_pack_readonly and
set_session(readonly=True) (defence in depth):
ReadOnlyRoleStatus(database='directus', user='context_pack_readonly',
transaction_read_only=True, is_superuser=False,
can_write_information_unit=False, can_write_unit_version=False,
can_write_lifecycle_log=False)
=> is_read_only = True
LiveDryRunDiscoverer.__init__ requires is_read_only — satisfied.
Visibility checks
| Surface | Visible? | Note |
|---|---|---|
public.information_unit / unit_version / iu_lifecycle_log |
YES | SELECT granted |
| ICX-CONST lifecycle state | YES | full survey ran (report 04) |
cutter_governance schema objects (catalog) |
YES | grant-matrix query works (catalog only) |
cutter_governance table data (SELECT) |
NO | SQLSTATE 42501 for context_pack_readonly |
pg_trigger / pg_proc (lifecycle triggers, fn md5) |
YES | catalog readable |
Grant matrix (orchestrator deployment_grant_matrix())
cutter_exec_execute_canonical_fns = True
cutter_verify_select_insert_verify_result = True
directus_select_review_decision = True
no_public_execute_leak = True
snapshot_sha = 45d25e38ac2dd440d0e7fdbdd6a5a20df11afbaef715002db4e46ea60bd2d600
The grant-matrix query needs only PG catalog access
(has_*_privilege, pg_proc, pg_class) — which context_pack_readonly
has — so it succeeds despite the no-SELECT-on-data limitation.
Documented limitation (macro G2 allowed path)
context_pack_readonly cannot SELECT cutter_governance table data.
Per macro G2 this is handled by limiting to the visible subset and
documenting — and crucially the dry-run is not actually limited:
in Mode.DRYRUN every phase body runs against the in-memory simulator,
so no cutter_governance data read is required to complete the run.
The only effect is that the before/after safety snapshot for
cutter_governance tables uses a supplementary directus read-only
session instead (see report 07). No User secret was requested.