Skip to content

security(state): provision least-privilege PostgreSQL roles - #208

Draft
seonghobae wants to merge 10 commits into
chatgpt/postgres-atomic-publication-redfrom
chatgpt/postgres-deployment-role-red
Draft

security(state): provision least-privilege PostgreSQL roles#208
seonghobae wants to merge 10 commits into
chatgpt/postgres-atomic-publication-redfrom
chatgpt/postgres-deployment-role-red

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Refs #80 #192. Draft child of exact #207@1d45a024f7e6a0cc351eda3b9fb317ccf6e35300.

This bounded durable-state slice moves the least-privilege publication-role contract out of #207's integration fixture and into an executable deployment artifact without enabling StateAuthority::Postgres, creating credentials, copying foreign-owner behavior, or widening Wardnet beyond its reputation/security state.

Executed RED and repair lineage

Initial test-only e1c6f7c3ef178f37c2ef15cb1c42f37ca0ea1ce1 added only tests/postgres_deployment_role_contract.rs; CI 34246722844 / rust 102130492398 stopped at rustfmt and is not semantic evidence. Concurrent formatting repair 0cf9fe514047b320a4aae1a9a1f8b96a8fb25053 was adopted rather than overwritten. Its CI 34247087136 / rust 102131737688 passed formatting and existing prerequisites, then produced the intended semantic RED because deploy/postgresql/reputation_state_roles.sql did not exist.

Concurrent production candidate ec93199dc3042f6c519592d300775b1d5f6e678a added only that non-migration deployment artifact. It idempotently creates/converges dedicated wardnet_state_owner and wardnet_runtime capability roles as NOLOGIN/NOSUPERUSER/NOCREATEDB/NOCREATEROLE/NOINHERIT/NOBYPASSRLS/NOREPLICATION, strips direct runtime mutation and inner-admission authority, transfers the outer SECURITY DEFINER publication function to the state owner with temporary schema CREATE revoked immediately afterward, and grants runtime only the reads plus outer publication EXECUTE needed by the repository boundary. CI 34247450830 / rust 102132975534 passed formatting and all preceding PostgreSQL 18.4 tests, installed and replayed the deployment artifact, then failed only because the Rust assertion expected PostgreSQL booleans as false/true while unaligned psql emits f/t; the observed role contract itself had the intended sixteen false and three true values. Exact 7167bdcd8e774a9b7f521e80765de1300e32f2ae corrected that oracle and CI 34247844928 / rust 102134327764 reached terminal SUCCESS.

The documentation-bearing 0d03523124905957a1bb0bbd8551fe0e85507b82 then added the matching Unreleased CHANGELOG entry and updated the Proposed publication ADR. Concurrent review immediately advanced the same branch with hostile atomicity test 282f0fec7ff16b3aa4e1e086900970e154e4f1c0; this intervening delta was adopted, not overwritten. Its hosted CI 34248558975 / rust 102137217073 passed formatting and all preceding PostgreSQL 18.4 acceptance, then failed exactly at postgres_deployment_role_atomicity: an injected ALTER FUNCTION failure stranded both capability roles and temporary state-owner schema CREATE (t:t:t instead of f:f:f). The root cause was psql autocommit across the installer statements.

Exact causal repair 03af6b3c962ce7d681bd49f5a80487aa94283bc6 wrapped the complete role installation in one explicit BEGIN/COMMIT transaction; hosted CI 34248937286 / rust 102138060537 was terminal SUCCESS. Follow-up documentation commits b1eee51598ccbbe24b200c28a9e387ce70365113 and current exact 5a4c510aad6a63c738fcf69656fa385e8343521b make the Proposed ADR and Unreleased CHANGELOG code-current with the executed atomicity RED/GREEN and PostgreSQL 18 rollback semantics. Hosted CI 34249592067 / rust 102140309527 is terminal SUCCESS on unchanged 5a4c510...: formatting, all locked workspace tests including the injected PostgreSQL 18.4 mid-flight rollback regression, and strict Clippy all passed. Predecessor receipts remain history only.

Acceptance

The executable PostgreSQL 18.4 contract requires idempotent replay; state owner and runtime NOLOGIN/NOSUPERUSER/NOBYPASSRLS properties; no residual state-owner schema CREATE; runtime no direct generation/publication/head mutation and no inner-admission EXECUTE; outer SECURITY DEFINER publication ownership by the state owner; successful runtime-mediated publication; denied direct runtime head mutation; denied state-owner schema DDL; unchanged last-known-good head after denied mutations; and all-or-nothing rollback of roles/grants/temporary schema authority on deterministic mid-flight installation failure.

Cluster-role installation remains a deployment operation after migrations 0001..0003. Login credentials/principals stay outside this artifact. Production PostgreSQL authority remains fail closed pending #80 repository wiring, actual deployment principal mapping, pooled tenant-context checkout/reset, migration upgrade/rollback/recovery, crash/retry, backup/restore and protected immutable release acceptance.

Keep Draft behind #140 -> #193 -> #194 -> #196 -> #198 -> #199 -> #200 -> #207. No force update, destructive rebase, self/model approval, routine bypass, gate weakening, predecessor-result transfer, mutable foreign dependency, or no-op workflow churn.

@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant