diff --git a/salt/postgres/files/schema/pillar/006_rls.sql b/salt/postgres/files/schema/pillar/006_rls.sql index 3b0da95ae..d18bd8ff4 100644 --- a/salt/postgres/files/schema/pillar/006_rls.sql +++ b/salt/postgres/files/schema/pillar/006_rls.sql @@ -28,6 +28,14 @@ BEGIN END $$; +-- USAGE on the schema is the bare minimum needed to reference its tables. +-- CONNECT on the database is needed before the role can establish a session +-- at all (default privileges on a new DB grant CONNECT to PUBLIC, but if the +-- securityonion database is restricted that grant has to be explicit). +-- Password + LOGIN privileges are set later in schema_pillar.sls because +-- the password lives in pillar (secrets:pillar_master_pass) and plain SQL +-- can't substitute pillar values. +GRANT CONNECT ON DATABASE securityonion TO so_pillar_master, so_pillar_writer, so_pillar_secret_owner; GRANT USAGE ON SCHEMA so_pillar TO so_pillar_master, so_pillar_writer, so_pillar_secret_owner; -- Read access for ext_pillar through the views only. @@ -37,15 +45,8 @@ GRANT SELECT ON so_pillar.v_pillar_global, TO so_pillar_master; GRANT EXECUTE ON FUNCTION so_pillar.fn_pillar_secrets(text) TO so_pillar_master; --- Engine reads + drains the change queue from the salt-master process. It --- needs SELECT to find unprocessed rows and UPDATE to mark them processed. --- The queue contains only locator metadata (no pillar data), so the master --- role's existing privilege footprint is unchanged in practice. -GRANT SELECT, UPDATE ON so_pillar.change_queue TO so_pillar_master; -GRANT USAGE ON SEQUENCE so_pillar.change_queue_id_seq TO so_pillar_master; --- Writer needs INSERT (the trigger runs as table owner, so this is just for --- direct testing / manual replays from psql). -GRANT INSERT ON so_pillar.change_queue TO so_pillar_writer; +-- (change_queue grants live in 008_change_notify.sql alongside the table itself, +-- since the table doesn't exist until 008 runs.) -- Writer needs CRUD on pillar_entry/minion/role_member plus access to seed tables. GRANT SELECT, INSERT, UPDATE, DELETE diff --git a/salt/postgres/files/schema/pillar/008_change_notify.sql b/salt/postgres/files/schema/pillar/008_change_notify.sql index 7fe22ad18..595e78b74 100644 --- a/salt/postgres/files/schema/pillar/008_change_notify.sql +++ b/salt/postgres/files/schema/pillar/008_change_notify.sql @@ -75,3 +75,15 @@ CREATE TRIGGER tg_pillar_entry_notify ON so_pillar.pillar_entry FOR EACH ROW EXECUTE FUNCTION so_pillar.fn_pillar_entry_notify(); + +-- Role grants on the change_queue table. Lived in 006_rls.sql historically but +-- moved here so the GRANT references resolve — 006 runs before this file does. +-- Engine reads + drains the change queue from the salt-master process. It +-- needs SELECT to find unprocessed rows and UPDATE to mark them processed. +-- The queue contains only locator metadata (no pillar data), so the master +-- role's existing privilege footprint is unchanged in practice. +GRANT SELECT, UPDATE ON so_pillar.change_queue TO so_pillar_master; +GRANT USAGE ON SEQUENCE so_pillar.change_queue_id_seq TO so_pillar_master; +-- Writer needs INSERT (the trigger runs as table owner, so this is just for +-- direct testing / manual replays from psql). +GRANT INSERT ON so_pillar.change_queue TO so_pillar_writer; diff --git a/salt/postgres/schema_pillar.sls b/salt/postgres/schema_pillar.sls index 6bd846c63..5d8c793af 100644 --- a/salt/postgres/schema_pillar.sls +++ b/salt/postgres/schema_pillar.sls @@ -93,13 +93,43 @@ so_pillar_master_key_configure: - require: - cmd: so_pillar_apply_{{ sql_files[-1] | replace('.', '_') }} +# Set login passwords on the so_pillar_* roles. 006_rls.sql creates the roles +# as NOLOGIN with no password (plain SQL can't substitute pillar values), so +# the salt-master ext_pillar and the pg_notify_pillar engine — both of which +# connect as so_pillar_master via TCP — would fail with "password +# authentication failed" without this step. The password lives in pillar +# under secrets:pillar_master_pass (generated by setup/so-functions::secrets_pillar) +# and is the same one rendered into ext_pillar_postgres.conf.jinja and the +# engines.conf pg_notify_pillar block, so all three sides agree. +so_pillar_role_login_passwords: + cmd.run: + - name: | + docker exec -i so-postgres psql -v ON_ERROR_STOP=1 -U postgres -d securityonion <