fix(deploy): tradein_fdw_reader password — psql var interpolation in DO block

psql :'pw' substitution НЕ работает внутри dollar-quoted блока $$..$$ — это
правило psql, не bug. Symptom: deploy 2026-05-24 после merge PR #503 упал с
'syntax error at or near :' on LINE 4 of set_tradein_fdw_password.sql, :'pw'
дошёл до сервера как literal вместо интерполяции.

Fix: передаём password в DO через session GUC (set_config) — psql интерполирует
:'pw' ВНЕ dollar quote, внутри читаем через current_setting(). Очищаем GUC
после выполнения (defense-in-depth).
This commit is contained in:
lekss361 2026-05-24 14:03:15 +03:00
parent 099b8e4b59
commit da7814810c

View file

@ -10,18 +10,26 @@
-- Combined with the regex whitelist on the backend side (fdw.py _PASSWORD_RE)
-- this gives defense-in-depth.
--
-- Extracted from deploy.yml inline DO block (PR #493 deploy/1156 incident).
-- The original block used multi-line backslash continuations inside a double-quoted
-- bash string with $$-dollar-quoting + psql variable substitution — fragile escaping
-- that likely caused the bootstrap step to fail before `compose up -d` ran.
-- Using `-f <file>` with psql-native variable substitution via `-v pw=` is safe.
-- psql variable substitution (:'pw') НЕ интерполируется внутри dollar-quoted
-- блока ($$...$$) — это правило psql, не bug. Поэтому password передаём в DO
-- через сессионный GUC (set_config), который psql интерполирует ВНЕ dollar
-- quote, и читаем внутри через current_setting().
-- Reference incident: deploy 2026-05-24 (post-merge PR #503) упал на
-- "syntax error at or near ':'" в LINE 4 этого файла — :'pw' дошёл до сервера
-- as literal вместо интерполяции.
SELECT set_config('app.fdw_pw', :'pw', false);
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tradein_fdw_reader') THEN
EXECUTE format('ALTER ROLE tradein_fdw_reader WITH PASSWORD %L', :'pw');
EXECUTE format('ALTER ROLE tradein_fdw_reader WITH PASSWORD %L', current_setting('app.fdw_pw'));
RAISE NOTICE 'tradein_fdw_reader password set';
ELSE
RAISE NOTICE 'tradein_fdw_reader role missing — migration 100_tradein_fdw_role.sql not applied yet';
END IF;
END $$;
-- Clear GUC after use (defense-in-depth — не оставляем password в session state
-- даже на short connection).
SELECT set_config('app.fdw_pw', '', false);