Unpinned authz-scope functions need explicit search_path design (pg_temp fleet finding)
Widened pg_temp sweep (PLUTO-664 follow-on) found fn_getInformesBundle, fn_getAlumnoDetailBundle, fn_getPracticasBundle -- the per-role scope-gate fns implementing rosterScope/scopedFacts CTEs (PLUTO-456/508 predicates) -- have NO search_path pin at all (proconfig has statement_timeout only, confirmed via proconfig dump not inference), plus unqualified refs throughout (rosterScope, scopedFacts, comisionFacts, jtpFacts, lookupOptions, vUsers, etc). fn_drain_email_outbox_if_due is also unpinned (unqualified emailOutbox EXISTS check gating an authenticated webhook). Unpinned = broader exposure than pinned-without-pg_temp-last (no schema constraint at all, not just a missing exclusion) -- sharpest finding in pluto's sweep, gates cross-role data access. FIX IS A DIFFERENT SHAPE than the 22+7 pinned fns in PLUTO-664: needs an explicit search_path SET from scratch (choosing the correct schema list), not a one-clause append -- Class-A, requires audit design-ping BEFORE any draft, do not fold into the mechanical pin-append migration.
Questions
Activity
-
Expression-index check (db-pluto-cc): fn_getAlumnoDetailBundle + fn_getPracticasBundle are LANGUAGE sql + UNPINNED (the fleet's risky pairing), fn_getInformesBundle + fn_drain_email_outbox_if_due are plpgsql (not inlining candidates regardless of pin). Full-DB expression-index enumeration found ZERO indexes referencing any of the 4 -- no index-silent-stop exposure. Design-ping for the from-scratch search_path choice is still the open item, unrelated to this axis.