Merge pull request 'fix(deploy): tradein_fdw_reader password — psql var interpolation in DO block' (#510) from fix/tradein-fdw-psql-var-in-do into main
Reviewed-on: #510
This commit is contained in:
commit
f04359592f
1 changed files with 30 additions and 6 deletions
|
|
@ -10,18 +10,42 @@
|
||||||
-- Combined with the regex whitelist on the backend side (fdw.py _PASSWORD_RE)
|
-- Combined with the regex whitelist on the backend side (fdw.py _PASSWORD_RE)
|
||||||
-- this gives defense-in-depth.
|
-- this gives defense-in-depth.
|
||||||
--
|
--
|
||||||
-- Extracted from deploy.yml inline DO block (PR #493 deploy/1156 incident).
|
-- psql variable substitution (:'pw') НЕ интерполируется внутри dollar-quoted
|
||||||
-- The original block used multi-line backslash continuations inside a double-quoted
|
-- блока ($$...$$) — это правило psql, не bug. Поэтому password передаём в DO
|
||||||
-- bash string with $$-dollar-quoting + psql variable substitution — fragile escaping
|
-- через сессионный GUC (set_config), который psql интерполирует ВНЕ dollar
|
||||||
-- that likely caused the bootstrap step to fail before `compose up -d` ran.
|
-- quote, и читаем внутри через current_setting().
|
||||||
-- Using `-f <file>` with psql-native variable substitution via `-v pw=` is safe.
|
-- Reference incident: deploy 2026-05-24 (post-merge PR #503) упал на
|
||||||
|
-- "syntax error at or near ':'" в LINE 4 этого файла — :'pw' дошёл до сервера
|
||||||
|
-- as literal вместо интерполяции.
|
||||||
|
--
|
||||||
|
-- ⚠️ `set_config(name, value, is_local) -> text` ВОЗВРАЩАЕТ установленное
|
||||||
|
-- значение. Без `\o /dev/null` бы psql напечатал password на stdout → leak в
|
||||||
|
-- Forgejo Actions deploy logs (retained, visible всем с repo read access).
|
||||||
|
-- Поэтому оборачиваем оба set_config вызова в `\o /dev/null` / `\o` brackets
|
||||||
|
-- — output mutes только для этих строк, NOTICE-сообщения из DO block
|
||||||
|
-- (idempotency signal) остаются видимыми.
|
||||||
|
--
|
||||||
|
-- Rollback path: НЕ revert этого файла (вернёт сломанный `:'pw'` внутри $$).
|
||||||
|
-- Корректный rollback — unset GENDESIGN_FDW_PASSWORD в /opt/gendesign/backend
|
||||||
|
-- /.env.runtime на VPS, deploy.yml тогда пропустит этот шаг полностью.
|
||||||
|
|
||||||
|
\o /dev/null
|
||||||
|
SELECT set_config('app.fdw_pw', :'pw', false);
|
||||||
|
\o
|
||||||
|
|
||||||
DO $$
|
DO $$
|
||||||
BEGIN
|
BEGIN
|
||||||
IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tradein_fdw_reader') THEN
|
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';
|
RAISE NOTICE 'tradein_fdw_reader password set';
|
||||||
ELSE
|
ELSE
|
||||||
RAISE NOTICE 'tradein_fdw_reader role missing — migration 100_tradein_fdw_role.sql not applied yet';
|
RAISE NOTICE 'tradein_fdw_reader role missing — migration 100_tradein_fdw_role.sql not applied yet';
|
||||||
END IF;
|
END IF;
|
||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
-- Clear GUC after use (defense-in-depth — не оставляем password в session state
|
||||||
|
-- даже на short connection). Same \o trick — set_config return value is empty
|
||||||
|
-- string here, но всё равно лишний row в stdout не нужен.
|
||||||
|
\o /dev/null
|
||||||
|
SELECT set_config('app.fdw_pw', '', false);
|
||||||
|
\o
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue