You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PostgreSQL remoteAccess: close the pg_hba.conf opening when a reload fails or the Service is removed #144
Found in the review of #141 (PostgreSQL remoteAccess, spec S-006). The nftables rule closes the port in each case below, so nothing is reachable from outside; these are gaps in the second layer.
1. A failed reload during removal leaves the old opening live
engine/ansible/roles/cloudfall_postgresql/tasks/main.yml (the removal path around lines 256 and 277): when remoteAccess is removed, the role deletes the Cloudfall block from pg_hba.conf and reloads. If that reload fails, the run fails, but the file is already without the block, so the next converge sees no change and never reloads. PostgreSQL keeps the old hostssl lines live until a restart.
Expected: a later converge notices that the running rules (pg_hba_file_rules or pg_settings) differ from the file and reloads, or the role reloads whenever the last reload didn't succeed.
2. Removing the whole Service leaves the block and the listener
S-006-10 covers removing remoteAccess from a service. Removing the PostgreSQL Service itself removes the firewall rule but leaves the pg_hba.conf block and listen_addresses = '127.0.0.1,<listenAddress>' on the host.
Expected: whatever the decommission path for a service is, it closes these too, or config validate/converge says what is left behind.
3. Reserved pg_hba words are refused only in the role
#141 makes the role refuse an owned database or owner named all, sameuser, samerole, samegroup or replication (pg_hba reads them as keywords). cloudfall config validate still accepts them, so the refusal comes at converge time. It should be CONFIG_INVALID with a context code at validate time.
engine/ansible/roles/cloudfall_postgresql/tasks/main.yml: the check and the reload run only when: cloudfall_postgresql_hba is changed. A failed reload during removal goes to the rescue, which removes the (already removed) block and fails; the next converge sees an unchanged file and never reloads, so PostgreSQL keeps the old hostssl lines until a restart
The role refuses an owned database or owner named all, sameuser, samerole, samegroup or replication; sdk/src/cloudfall/validation.py doesn't, so the refusal comes only at converge
The plan:
Part 1: make a reload that didn't succeed get retried on the next converge. The rescue leaves a marker file on the host (under the role's own state, not in pg_hba.conf); the next run reloads when the file changed or the marker is there, and removes the marker once pg_reload_conf() returns t. A run with neither stays unchanged, so converge stays idempotent
Part 3: config validate refuses those names when the service declares remoteAccess, as CONFIG_INVALID with the context code service_remote_access_name_reserved, pointing at the database's name or owner. The role keeps its own check as the second layer
Tests: a role test for the marker path (rescue writes it, the next run reloads and clears it) and validation tests for each reserved word as a name and as an owner; a service without remoteAccess may still use them, as today
@romamo Decided without waiting: cloudfall config validate refuses a PostgreSQL service with remoteAccess whose owned database or owner is named all, sameuser, samerole, samegroup or replication, with the new context code service_remote_access_name_reserved.
Why: converge already refuses exactly these configs (#141), so no config that works today stops working; the refusal only moves to validate, where every other remoteAccess mistake is caught.
Not taken: leave the refusal in the role alone, which means the mistake surfaces only after a converge has started on the host.
Reply with a comment starting with veto before 2026-10-28 11:15 UTC to reverse it, adding what you want instead if you like. A later veto still counts and gets a follow-up.
The fix is in #147. Part 1: when the pg_hba check or reload fails, the rescue leaves /var/lib/cloudfall/postgresql/<service id>.pg_hba-reload-pending (a new root-only state directory), the next converge checks and reloads even though the file no longer changes, then removes the marker; a run with neither stays changed=0. Part 3: config validate refuses the five pg_hba keywords as an owned database's name or owner on a service with remoteAccess (service_remote_access_name_reserved), and S-006-11 lists the new code. Not verified live: a real pg_reload_conf() failure on a host; the test replays the role's block against a stub psql. Part 2 is #146. This issue closes when #147 merges.
Released in v0.8.0rc7 (pre-release). uv tool install --prerelease allow cloudfall==0.8.0rc7
A plain install gets it with the next stable release.
If you filed this: react 👍 on this comment once it works for you, or reply if it doesn't.
Activity
shipmill-romamo commentedon Oct 27, 2026
Triage: implement parts 1 and 3, for the next release candidate. Part 2 moves to #146, postponed.
Confirmed on main (2828e49) by reading the code:
engine/ansible/roles/cloudfall_postgresql/tasks/main.yml: the check and the reload run onlywhen: cloudfall_postgresql_hba is changed. A failed reload during removal goes to the rescue, which removes the (already removed) block and fails; the next converge sees an unchanged file and never reloads, so PostgreSQL keeps the oldhostssllines until a restartall,sameuser,samerole,samegrouporreplication;sdk/src/cloudfall/validation.pydoesn't, so the refusal comes only at convergeThe plan:
pg_hba.conf); the next run reloads when the file changed or the marker is there, and removes the marker oncepg_reload_conf()returnst. A run with neither stays unchanged, so converge stays idempotentconfig validaterefuses those names when the service declaresremoteAccess, asCONFIG_INVALIDwith the context codeservice_remote_access_name_reserved, pointing at the database'snameorowner. The role keeps its own check as the second layerremoteAccessmay still use them, as todayI'll link the PR here.
shipmill-romamo commentedon Oct 27, 2026
@romamo Decided without waiting:
cloudfall config validaterefuses a PostgreSQL service withremoteAccesswhose owned database or owner is namedall,sameuser,samerole,samegrouporreplication, with the new context codeservice_remote_access_name_reserved.Why: converge already refuses exactly these configs (#141), so no config that works today stops working; the refusal only moves to validate, where every other
remoteAccessmistake is caught.Not taken: leave the refusal in the role alone, which means the mistake surfaces only after a converge has started on the host.
Reply with a comment starting with
vetobefore 2026-10-28 11:15 UTC to reverse it, adding what you want instead if you like. A later veto still counts and gets a follow-up.shipmill-romamo commentedon Oct 27, 2026
The fix is in #147. Part 1: when the pg_hba check or reload fails, the rescue leaves
/var/lib/cloudfall/postgresql/<service id>.pg_hba-reload-pending(a new root-only state directory), the next converge checks and reloads even though the file no longer changes, then removes the marker; a run with neither stayschanged=0. Part 3:config validaterefuses the five pg_hba keywords as an owned database's name or owner on a service withremoteAccess(service_remote_access_name_reserved), and S-006-11 lists the new code. Not verified live: a realpg_reload_conf()failure on a host; the test replays the role's block against a stubpsql. Part 2 is #146. This issue closes when #147 merges.shipmill-romamo commentedon Oct 27, 2026
Released in v0.8.0rc7 (pre-release). uv tool install --prerelease allow cloudfall==0.8.0rc7
A plain install gets it with the next stable release.
If you filed this: react 👍 on this comment once it works for you, or reply if it doesn't.