From a5cdc6b1ccbce61dff823fc77d68f17db15aa622 Mon Sep 17 00:00:00 2001 From: "shipmill-romamo[bot]" <338557544+shipmill-romamo[bot]@users.noreply.github.com> Date: Fri, 30 Oct 2026 14:48:34 +0200 Subject: [PATCH] Record D-9: owner passwords reach PostgreSQL only as a SCRAM verifier (#140) Co-Authored-By: Claude Opus 5.5 --- docs/decisions.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/decisions.md b/docs/decisions.md index 03553f6..5d442ec 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -67,3 +67,11 @@ entry that supersedes it, never by editing an old one. - Why: All three come from the model's output, which can quote host output; structured arguments can't be cut and stay meaningful, so refusing keeps steps[] a true account of what ran - Applies to: sdk/src/cloudfall/investigation.py, config/schemas/v1/agent-investigation.schema.json - Enforced by: review + +## D-9: Owner passwords reach PostgreSQL only as a SCRAM verifier + +- Decided: 2026-10-30, in cloudfall-dev/cloudfall#140 +- Rule: Cloudfall sets a PostgreSQL role's password only with a SCRAM-SHA-256 verifier computed on the controller; the plaintext password is never staged on the host and never sent to the server, so it can't reach the PostgreSQL log or pg_stat_activity +- Why: psql substitutes a variable into the statement text, so ALTER ROLE ... PASSWORD with the plaintext puts the password in the server's log under log_statement ddl or all, or on a failing statement; PostgreSQL stores a pre-hashed verifier as it is +- Applies to: engine/ansible/roles/cloudfall_postgresql/tasks/owner_password.yml, sdk/src/cloudfall/secrets.py, engine/src/cloudfall_engine/cli.py +- Enforced by: a regression test that the staged file holds a verifier and never the password