fleetanalytics_mcp/pgbouncer/auth_setup.sql

41 lines
1.9 KiB
MySQL
Raw Normal View History

-- auth_setup.sql — create the PgBouncer auth_query plumbing on tracksolid_db.
-- ─────────────────────────────────────────────────────────────────────────────
-- Run ONCE as the postgres SUPERUSER (the SECURITY DEFINER function must be owned by
-- a superuser to read pg_shadow). Apply with:
-- docker exec -i <timescale_db> psql -U postgres -d tracksolid_db \
-- -v ON_ERROR_STOP=1 -v pgb_pw="$(cat ~/.pgbouncer_auth.pw)" < auth_setup.sql
--
-- This lets PgBouncer authenticate ANY app user by looking its stored SCRAM verifier
-- up at connect time — so you never hand-maintain a userlist of every app password.
-- Only the pgbouncer_auth role itself needs an entry in userlist.txt.
\set ON_ERROR_STOP on
-- 1) A minimal LOGIN role PgBouncer uses to run the lookup. No other privileges.
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'pgbouncer_auth') THEN
CREATE ROLE pgbouncer_auth LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE;
END IF;
END $$;
ALTER ROLE pgbouncer_auth WITH LOGIN PASSWORD :'pgb_pw';
-- 2) The lookup function. SECURITY DEFINER (owned by postgres) so it can read
-- pg_shadow; returns exactly (username, scram_verifier) for one user.
CREATE SCHEMA IF NOT EXISTS pgbouncer AUTHORIZATION postgres;
CREATE OR REPLACE FUNCTION pgbouncer.user_lookup(
IN i_username text, OUT uname text, OUT phash text
) RETURNS record
LANGUAGE sql
SECURITY DEFINER
SET search_path = pg_catalog
AS $$
SELECT usename, passwd FROM pg_catalog.pg_shadow WHERE usename = i_username;
$$;
-- 3) Lock the function down to ONLY pgbouncer_auth.
REVOKE ALL ON FUNCTION pgbouncer.user_lookup(text) FROM public;
GRANT USAGE ON SCHEMA pgbouncer TO pgbouncer_auth;
GRANT EXECUTE ON FUNCTION pgbouncer.user_lookup(text) TO pgbouncer_auth;