basquetWi + New ticket
mars MARS-803

supautils force-grant census: public functions holding EXECUTE outside their allowed set (R6 forbidden-set read, inventory only)

Done low dmdb-mars-ca

Census only, READ-ONLY, with no REVOKE or GRANT authority attached. Hygiene priority, so it queues behind anything user-facing. Origin: EVO-114. pmmaster scoped the census to projects where the supautils function force-grant matrix in evolutiva-db.md reads YES (Mars, Pluto, Enamel; Venus NO, no row). Predicate to census against: the R6 forbidden-set shape in evolutiva-db.md (Migration File Discipline, plus the supautils section postflight line fixed in 78d3e7d). For every public-schema function, read aclexplode(coalesce(proacl, acldefault('f', proowner))) and list each grantee outside that function's allowed set, including PUBLIC (grantee=0), anon, authenticated and any stray app role. Also report which flagged functions are SECURITY DEFINER, and whether the creating migration carries the explicit same-migration REVOKE. Output is the inventory on this row. Any closure is a separate row with its own audit. Context: the Data API is disabled on all projects (Elazar ruling, evolutiva-db.md), so this is not a live hole.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • coder-mars-cc created · 1w ago
  • coder-mars-ca note · 1w ago
    coder-mars-ca refused 2026-10-06 PM dispatch: production pg_catalog census is already assigned to db-mars-ca and requires that seat's named Mars DB read credential; coder seat holds none. Assignment unchanged; no read attempted.
  • db-mars-ca note · 1w ago
    Read-only live catalog census, Mars project ustenjufophwhlkzfdso, role agent_db_mars_ca. Per R6, effective function ACL expanded with acldefault when proacl is NULL. No REVOKE/GRANT performed. Exact inventory SQL: BEGIN TRANSACTION READ ONLY; WITH f AS (SELECT p.oid,n.nspname,p.proname,pg_get_function_identity_arguments(p.oid) args,pg_get_userbyid(p.proowner) owner_name,p.proowner,p.prosecdef,a.grantee,pg_get_userbyid(a.grantor) grantor FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace CROSS JOIN LATERAL aclexplode(coalesce(p.proacl,acldefault('f',p.proowner))) a WHERE n.nspname='public' AND a.privilege_type='EXECUTE') SELECT nspname||'.'||proname||'('||args||')' function_identity,owner_name,prosecdef,CASE WHEN grantee=0 THEN 'PUBLIC' ELSE pg_get_userbyid(grantee) END grantee,grantor FROM f WHERE grantee<>proowner AND grantee<>0 AND pg_get_userbyid(grantee) NOT IN ('postgres','service_role','mars_app_runtime') ORDER BY function_identity,grantee; SELECT count(DISTINCT p.oid) public_function_count,count(DISTINCT p.oid) FILTER(WHERE p.prosecdef) security_definer_count FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE n.nspname='public'; SELECT CASE WHEN a.grantee=0 THEN 'PUBLIC' ELSE pg_get_userbyid(a.grantee) END grantee,count(DISTINCT p.oid) function_count FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace CROSS JOIN LATERAL aclexplode(coalesce(p.proacl,acldefault('f',p.proowner))) a WHERE n.nspname='public' AND a.privilege_type='EXECUTE' AND a.grantee<>p.proowner GROUP BY 1 ORDER BY 1; COMMIT; Results: 74 public functions, 5 SECURITY DEFINER. Expanded ACL recipient counts: service_role 74 functions, mars_app_runtime 20, evolutiva_agent_ro 4, evolutiva_agent_rw 5, applog_reader 1; zero PUBLIC, anon, authenticated recipient entries. Per-function additional grants to agent roles are intentional and explicitly enumerated in migrations 063/072/091/118/146; mars_app_runtime grants are the app allowlist (128 plus scoped later grants). Sole grant not matched to a tracked per-function grant declaration: applog_reader on public.fn_dbperf_statements_top50(), grantor postgres, SECURITY DEFINER. Source migration 010 creates/replaces it and contains no same-migration REVOKE; repo search finds no later tracked GRANT/REVOKE for applog_reader on this function. Thus inventory flags an ACL provenance/allowset gap, not PUBLIC/anon/authenticated access. No ACL change recommended or made. Supabase Data API is disabled per standing project ruling, so this is not an HTTP client exposure finding. Coverage: catalog is current live state at query time; source attribution is only against checked-in migrations and cannot prove who/when applied an untracked/manual grant. Exact named agent-role helper grants are documented as intended; fn_dbperf applog_reader authorization needs owner provenance/allowset clarification in a separate decision/change.
  • db-mars-ca note · 1w ago
    Completeness gate: compared all 20 live mars_app_runtime function EXECUTE grants against migration 139's 17 app-call signatures plus explicit later additions fn_assert_admin_invariant (132), fn_normalize_archive_reason (134), and fdi_tooth_class (168): 0 unexpected, 0 missing. Documented agent-role grants match per-function grants in 063, 072, 091, 118/146. service_role is the R6 allowed baseline; no PUBLIC/anon/authenticated ACL rows. The only role outside the documented per-function sets is applog_reader on fn_dbperf_statements_top50, already separately recorded. Same-migration REVOKE check for this flagged SECURITY DEFINER function: absent in source migration 010. Follow-up MARS-804 created for provenance/allowset resolution; no ACL change.
  • db-mars-ca completed · 1w ago
    Read-only R6 catalog census complete under agent_db_mars_ca; full allowed-set comparison recorded. One undocumented applog_reader grant is isolated to MARS-804; no ACL changed.
chore
1w ago by coder-mars-cc
1w ago
2026-10-06 15:30