pg_net EXECUTE to PUBLIC: measure whether this ref grants net.http_post to every login role
Per-ref leg of ENAMEL-35 (db-enamel-cc, 2026-09-11). MEASURED on ref eprpywqwzsvrjeaforei: proacl is NULL on every net.* function, which means EXECUTE to PUBLIC, and has_function_privilege on net.http_post returns TRUE for all THIRTEEN login roles including supabase_read_only_user, applog_writer and venusApp. Consequence: any DB credential on that ref is an arbitrary outbound-HTTP primitive with the database as origin, plus net.worker_restart. Table grants do not bound it and no per-relation privilege audit surfaces it. Root cause is upstream: extensions.grant_pg_net_access() contains the correct REVOKE ... FROM PUBLIC but gates it on extversion IN ('0.2'...'0.11.0') under the comment '0.12.0 onwards dont need these applied'; that ref runs 0.20.3 so it never fires and the premise is false. SCOPE FOR THIS REF, read-only: (1) select extversion from pg_extension where extname='pg_net'; (2) has_function_privilege per login role on net.http_post, net.http_get and net.worker_restart; (3) proacl on every net.* function. VERSION IS THE DISCRIMINATOR - do not inherit enamels result, measure this ref. DO NOT WRITE A REVOKE MIGRATION: as postgres the REVOKE raises no error and changes nothing, because a non-owner revoke warns rather than failing, so the migration would ship green and fix nothing; set role supabase_admin is 42501. Remediation is a Supabase support request or an explicit accept-the-condition, and that routes to Elazar.
Activity
-
db-mars-cc
-
Reassigned to db-mars-cc. This is a read of pg_extension and has_function_privilege on a production ref, and the fleet rule is that no agent queries a DB whose maintenance lane it does not own. db-mars-cc owns the Mars DB lane; I do not. Scope is unchanged and the DO-NOT-WRITE-A-REVOKE constraint in the description stands - as postgres the REVOKE raises no error and changes nothing, so the migration would ship green and fix nothing.
-
MEASURED ON REF ustenjufophwhlkzfdso (Mars), db-mars-cc 2026-09-11, read-only plus one rolled-back probe. The condition is CONFIRMED and it is WIDER here than on enamel - but the remediation is NOT the same, and that is the part this leg adds. (1) VERSION - the discriminator, measured not inherited: pg_net 0.20.0, schema extensions. extensions.grant_pg_net_access() still gates its REVOKE ... FROM PUBLIC on extversion IN ('0.2'...'0.11.0') - I read the body, prosrc matches both '0.12.0' and 'extversion IN'. 0.20.0 is outside the list, so the REVOKE has never fired on this ref. Same false premise as enamel, independently confirmed. (2) SCOPE - all 12 net.* functions have proacl NULL (= EXECUTE to PUBLIC), owner supabase_admin. And the schema leg is open too, which enamel's read did not cover: pg_namespace.nspacl on net is {supabase_admin=UC, =U/supabase_admin, supabase_functions_admin=U, postgres=U, anon=U, authenticated=U, service_role=U} - the bare '=U' is USAGE TO PUBLIC. Both gates are open, so there is nothing bounding it. (3) EIGHTEEN login roles, not thirteen. has_function_privilege returns TRUE on net.http_post, net.http_get AND net.worker_restart for every rolcanlogin role on the ref, and has_schema_privilege(net,USAGE) is TRUE for all 18: agent_audit_mars_ca, agent_db02_mars_cc, agent_db_mars_cc, applog_reader, applog_writer, authenticator, errscan_ro, evolutiva_agent_notify, mars_app_runtime, pgbouncer, postgres, supabase_admin, supabase_auth_admin, supabase_etl_admin, supabase_functions_admin, supabase_read_only_user, supabase_replication_admin, supabase_storage_admin. Note errscan_ro, applog_reader and supabase_read_only_user - roles whose entire purpose is read-only are arbitrary outbound-HTTP primitives with the database as origin. (4) THE NO-OP CLAIM IS TRUE AND I PROVED IT RATHER THAN QUOTING IT. In a rolled-back transaction as postgres: REVOKE EXECUTE ON FUNCTION net.http_post(...) FROM PUBLIC emits 'WARNING: no privileges could be revoked for "http_post"' and then reports REVOKE - a WARNING, not an ERROR, so ON_ERROR_STOP does not catch it and psql exits 0. proacl afterwards materialises from NULL to {=X/supabase_admin,supabase_admin=X/supabase_admin} - PUBLIC still holds X. A revoke migration would ship green, pass every assertion, and change nothing. Confirmed: do not write one. (5) THE FINDING THIS LEG ADDS, AND IT CHANGES WHAT REMEDIATION HAS TO LOOK LIKE: MARS ACTUALLY USES pg_net, in six live places, and every one of them runs as postgres whose EXECUTE comes ONLY from PUBLIC. public.drain_email_outbox_if_due (INVOKER, owner postgres, search_path='pg_catalog, public, net') calls net.http_post and is driven by cron job 6 every 5 minutes; cron jobs 13, 14, 15 and 16 call net.http_get directly (weekly-kpi, reminders, digests), job 18 is the same shape but inactive. All username=postgres. So a bare REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA net FROM PUBLIC - which is exactly what a support ticket would most naturally ask for, and what extensions.grant_pg_net_access() itself would do if its version gate were fixed upstream - TAKES MARS'S ENTIRE OUTBOUND CRON SURFACE DOWN: no email drain, no weekly KPI, no reminders, no watchdog. Silently, because those calls are inside cron jobs nobody watches. THEREFORE the ask that goes to Elazar/Supabase must be REVOKE FROM PUBLIC **PAIRED WITH** an explicit GRANT EXECUTE ON net.http_post(text,jsonb,jsonb,jsonb,integer) AND net.http_get(text,jsonb,jsonb,integer) TO postgres, in the same operation. Revoke-only is a production outage on this ref. Not actionable from the db lane either way - as postgres the GRANT is as ineffective as the REVOKE (non-owner), and 'set role supabase_admin' is 42501. NOT MEASURED, stated so nobody reads this as complete: whether the other Evolutiva refs share the version and therefore the condition. This leg covers ustenjufophwhlkzfdso only.
-
MEASURE LEG IS COMPLETE (see the verified event 2026-09-11). This row stays OPEN because remediation is not actionable by any agent and has not been decided. Two facts bound the decision: (a) as postgres both REVOKE and GRANT on net.* are no-ops that report success - proven in a rolled-back txn, WARNING not ERROR - and 'set role supabase_admin' is 42501, so this can only move via a Supabase support request or an explicit accept-the-condition; (b) Mars USES pg_net in six live places, all running as postgres whose EXECUTE comes only from PUBLIC, so the naive revoke-only remediation silently takes down email drain, weekly KPI, reminders and the watchdog. The ask must be REVOKE FROM PUBLIC PAIRED WITH GRANT EXECUTE ON net.http_post/net.http_get TO postgres in one operation. ELAZAR'S CALL.
-
NAMED CONSUMER ADDED, db-mars-cc 2026-09-11, per coder-mars-cc decision 4 on MARS-711. The MARS-711 disk-fill alarm is designed to egress via net.http_get, which makes it a CONSUMER of the exact grant this row proposes to revoke. Current consumer list of postgres's PUBLIC-derived EXECUTE on net.*: drain_email_outbox_if_due (cron job 6, every 5 min), cron jobs 13/14/15/16 (weekly-kpi, reminders, digests - direct net.http_get), the cron watchdog, and now the MARS-711 WAL/archiver alarm. A bare REVOKE ... FROM PUBLIC silently disables all of them. This strengthens rather than changes the recorded ask: REVOKE PAIRED WITH GRANT EXECUTE ON net.http_post(text,jsonb,jsonb,jsonb,integer) AND net.http_get(text,jsonb,jsonb,integer) TO postgres, in ONE operation. Elazar's call, unchanged.
-
NAMED CONSUMER ADDED, db-mars-cc 2026-09-11, per coder-mars-cc decision 4 on MARS-711. The MARS-711 disk-fill alarm is designed to egress via net.http_get, which makes it a CONSUMER of the exact grant this row proposes to revoke. Current consumers of postgres's PUBLIC-derived EXECUTE on net.*: drain_email_outbox_if_due (cron job 6, every 5 min), cron jobs 13/14/15/16 (weekly-kpi, reminders, digests - direct net.http_get), the cron watchdog, and now the MARS-711 WAL/archiver alarm. A bare REVOKE ... FROM PUBLIC silently disables all of them. This strengthens rather than changes the recorded ask: REVOKE PAIRED WITH GRANT EXECUTE ON net.http_post(text,jsonb,jsonb,jsonb,integer) AND net.http_get(text,jsonb,jsonb,integer) TO postgres, in ONE operation. Elazar's call, unchanged.
-
ROUTING NOTE, so this row does not sit looking like it is waiting on a message that was never delivered. I attempted to DM the decision ask to Elazar over the hub; the hub REFUSED it - humanincdw=false, he is CLI-only, nothing was stored and nothing was relayed. Do not record this as 'sent to Elazar'. The two options were put to him directly in the coder-mars-cc CLI instead, verbatim as recorded here: (a) Supabase support request wording REVOKE EXECUTE ON ALL FUNCTIONS IN SCHEMA net FROM PUBLIC paired in the SAME operation with GRANT EXECUTE ON net.http_post(text,jsonb,jsonb,jsonb,integer) and net.http_get(text,jsonb,jsonb,integer) TO postgres, or (b) accept the condition and I close this as accepted-risk. Row stays blocked on that answer; nothing further is actionable from any agent lane and no further measurement is owed. Reusable point: the hub refuses rather than buffers for Elazar, so an agent that sends and moves on believes it has escalated and has not - the failure is silent in the direction of looking done.
-
NARROWING MY OWN ENTRY, db-mars-cc 2026-09-11, agreeing with coder-mars-cc: the MARS-711 alarm as SHIPPED has no pg_net egress at all - the design reached for net.http_get and then rejected it, because pg_net enqueues into net.http_request_queue and that enqueue is a database write which fails under forced read-only exactly as appEvents does. So it must NOT be counted among the things a bare revoke would break. It stays listed here as DESIGN RATIONALE only, because the reason pg_net was rejected belongs next to the revoke decision. The live consumer list is unchanged and is what the ask rests on: drain_email_outbox_if_due (cron job 6, every 5 min) and cron jobs 13/14/15/16 calling net.http_get directly, all running as postgres whose EXECUTE comes only from PUBLIC.
-
WIDER RE-MEASURE ON REF ustenjufophwhlkzfdso, db-mars-cc 2026-09-11, at pmmaster's request after PLUTO-736. MEASURE ONLY - nothing revoked, granted or altered. ALL THREE PLUTO FINDINGS CONFIRMED ON MARS, plus two additions, plus one Mars-specific ESCALATION that changes what this row is about. Q1 SCHEMA USAGE TO PUBLIC - CONFIRMED. pg_namespace.nspacl for net = {supabase_admin=UC, =U/supabase_admin, supabase_functions_admin=U, postgres=U, anon=U, authenticated=U, service_role=U}. The bare '=U' is USAGE to PUBLIC. Q2 TABLE ACLS - CONFIRMED, AND WIDER THAN PLUTO REPORTED. Both net.http_request_queue and net._http_response carry relacl {supabase_admin=arwdDxtm, =arwdDxtm/supabase_admin} - PUBLIC holds SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES and TRIGGER on both. ADDITION: the sequence net.http_request_queue_id_seq carries {supabase_admin=rwU, =rwU/supabase_admin}, so PUBLIC also holds SELECT/UPDATE/USAGE on it - i.e. setval is reachable, which is a queue-corruption primitive pluto's list did not name. net._http_response holds 5 rows right now, oldest 2026-09-11 11:00:00Z, so retention is hours rather than permanent but the content IS live and PUBLIC-readable (columns: id, status_code, content_type, headers, content, timed_out, error_msg, created). Q3 'EVERY LOGIN ROLE' IS THE WRONG SENTENCE - CONFIRMED. With the rolcanlogin filter REMOVED, 23 non-login roles all test TRUE on all five of: USAGE on net, EXECUTE on net.http_post, SELECT on net._http_response, TRUNCATE on net._http_response, INSERT on net.http_request_queue. That includes anon, authenticated, service_role, dashboard_user, evolutiva_agent_ro, evolutiva_agent_rw, pg_read_all_data and every other predefined role. Combined with my earlier 18 login roles, the correct statement is PUBLIC, not 'every credential'. *** THE ESCALATION, MARS-SPECIFIC AND I DID NOT EXPECT IT: PUBLIC READ ON net.http_request_queue CIRCUMVENTS MARS-380. *** net.http_request_queue has a 'headers' column, and five Mars cron jobs (13, 14, 15, 16 and the inactive 18) call net.http_get with headers built from public.cron_auth_header() - measured by pattern, not by reading any value: headers clause present TRUE, references cron_auth_header TRUE, literal bearer in the command FALSE on all five. cron_auth_header() returns the CRON_SECRET bearer, and MARS-380 plus migration 128 revoked that function from client-reachable roles ON PURPOSE; it is a standing fleet constraint that it stays revoked. But pg_net does not send inline - it ENQUEUES, headers included, into a table PUBLIC can SELECT. So the secret the revoke protects lands in PUBLIC-readable storage every time one of those jobs fires. The queue is EMPTY right now (0 rows - the worker deletes on drain), so this is a TRANSIENT window rather than standing storage, and I am stating it as a timing exposure rather than a disclosure: anyone holding any role on this ref who polls that table during a cron fire can capture the bearer. I did not read, print or store any header value; the counts above are presence-only predicates. BOUND (a) HOLDS IDENTICALLY ON MARS AND I CHECKED IT RATHER THAN INHERITING IT: pg_db_role_setting has ZERO rows matching pgrst|db_schema|db-schema, so the exposed-schema list is not readable from the database here either. Nobody upgrades this to 'unauthenticated internet egress' without a dashboard check. MARS DIVERGES IN A REASSURING DIRECTION, stated with the same caveat: Mars's Data API is disabled via db-schemas=pg_pgrst_no_exposed_schemas (measured 2026-09-11), which is stronger than 'net is not in the default list' - no schema is exposed at all. That control is a DASHBOARD TOGGLE WITH NO DB-SIDE TRACE, so it carries exactly the unverifiable-state caveat pluto applied and must not be leant on as a guarantee. COVERAGE BOUND ON THIS MEASUREMENT: ref ustenjufophwhlkzfdso only; catalog reads plus has_*_privilege predicates; no attempt to exercise any privilege as anon or authenticated, so this establishes what the ACLs GRANT and not what a given client can reach end to end. The remediation position is unchanged and is Elazar's: REVOKE FROM PUBLIC PAIRED WITH GRANT EXECUTE ON net.http_post/net.http_get TO postgres in ONE operation - and it should now also cover the two tables and the sequence, not only the functions.
-
WIDE RE-MEASURE AND TWO RETRACTIONS OF MY OWN EARLIER WORDING, db-mars-cc 2026-09-11, at pmmaster's request after db-venus-cc found a caller no cron-scoped instrument reaches. Measure only, nothing altered, presence predicates throughout - no value read, printed or stored. RETRACTION 1 - 'TIMING EXPOSURE' WAS WRONG FOR HALF THE FINDING. pg_net.ttl on this ref is 6 HOURS (source: default). net._http_response holds 5 rows spanning 05:21:50 (oldest 2026-09-11 11:00:00Z, newest 16:21:50Z) with columns id, status_code, content_type, headers, content, timed_out, error_msg, created. So RESPONSE headers and bodies are PUBLIC-readable for six hours BY CONFIGURATION, and a role polling once per ttl captures everything without ever catching a request in flight. The bearer side is still genuinely flight-time - net.http_request_queue holds 0 rows because the worker deletes on drain - but calling the whole finding a timing exposure understated it. The two sides have different exposure models and must be written up separately. RETRACTION 2 - MY CALLER SET WAS SCOPED TO cron.job AND THEREFORE MISSED A TRIGGER. Re-run wide, starting from pg_proc with no reachability filter: every function catalog-wide whose prosrc names net.http_ is exactly TWO - public.drain_email_outbox_if_due (INVOKER, owner postgres, headers clause TRUE, references a secret function TRUE, literal bearer FALSE) and extensions.grant_pg_net_access (the version-gated one that never ran). AND drain_email_outbox_if_due IS REACHED BY A TRIGGER, not only by cron: trg_emailOutbox_wakeDrainOnEnqueue on public."emailOutbox" -> wake_email_drain_on_enqueue (SECURITY DEFINER, owner postgres, migration 138) -> drain_email_outbox_if_due -> net.http_post, firing on natural enqueue. So the exposure window on this ref is cron */5 AND the four active http_get cron jobs AND whenever a row lands in the outbox. I had cited migration 138 twice today and still missed it, because I scoped the search by cron.job and the trigger was never on cron. Mars detail: that trigger is tgenabled='O', not 'A', so unlike Mars's archive triggers it IS bypassed under session_replication_role=replica. BOTH INSTRUMENTS ARE REQUIRED AND NEITHER SUBSUMES THE OTHER: cron jobs 13/14/15/16 (+ inactive 18) call net.http_get from cron COMMAND TEXT, not from any function body, so the wide pg_proc scan does not return them. Running only the wide instrument on this ref reports 2 callers and misses 5. FOURTH WIDENING ATTEMPTED RATHER THAN ASSUMED: scanned views and matviews via pg_get_viewdef, rules via pg_get_ruledef, column defaults via pg_get_expr, and check constraints, for net\.http_. Nothing new - only the 5 cron commands and net.http_request_queue.id's own sequence default. Complete in-database caller set on this ref: 2 functions + 5 cron commands, one function trigger-reachable. WHAT THIS INSTRUMENT STILL CANNOT SEE, recorded because a clean verdict here would be false comfort: (1) callers OUTSIDE the database - application code issuing net.http_post over an ordinary connection is invisible to any catalog scan, and mars_app_runtime holds EXECUTE, so closing this needs a src/ grep by the push lane; (2) attribution of retained responses to a specific job - _http_response has no url column and the matching queue rows are gone, so cadence is inference (db-venus-cc's bound, identical here); (3) whether any retained body or header actually contains anything sensitive - content was not read by rule, so 'PUBLIC can read six hours of responses' is a grant-plus-retention fact and NOT a disclosure claim; (4) dynamic SQL - a function concatenating 'net.http_' would not match the regex and I did not scan for it. THREE OF MY INSTRUMENTS ON THIS ROW REPORTED CLEAN-OR-NARROW BEFORE BEING WIDENED: nspacl pattern-matched for '=U' (missed that PUBLIC and four named grants are independent paths), callers scoped to cron.job (missed the trigger), and a queue row count without reading the ttl (missed six-hour response retention). Each widening found something. Assume a fifth exists in item (1).
-
CADENCE CORRECTED - 'RATE' WAS WRONG, 'WINDOW' IS RIGHT, db-mars-cc 2026-09-11. Third retraction of my own wording on this row, and like the other two it made the finding read as narrower or wider than it is rather than changing its severity. ARITHMETIC VALIDITY ESTABLISHED FIRST, because a row count is only a fire count if collection does not consume: on this ref net._http_collect_response, net.http_collect_response and net._await_response ALL contain no DELETE and no TRUNCATE in prosrc. Collection is non-consuming here, so retained rows = fires. That check is ref-specific and was not assumed. BOTH MARS PATHS ARE CONDITIONAL, same shape db-venus-cc measured on venus. (1) public.drain_email_outbox_if_due calls net.http_get ONLY inside IF EXISTS(status='pending' AND "nextAttemptAt" <= now()) OR EXISTS(status='sending' AND "claimedAt" < now() - interval '5 minutes'); otherwise it returns having made no HTTP call. (2) trg_emailOutbox_wakeDrainOnEnqueue is AFTER INSERT ... REFERENCING NEW TABLE AS newrows FOR EACH STATEMENT, and wake_email_drain_on_enqueue only calls the drain inside IF EXISTS(SELECT 1 FROM newrows WHERE status='pending' AND "nextAttemptAt" <= now()). Two consequences: a future-scheduled or retry-backoff row does NOT wake it, and being statement-level over the transition table, a multi-row enqueue fires exactly ONE wake rather than one per row. MEASURED RATHER THAN DERIVED FROM CADENCE: public."emailOutbox" holds 560 rows, ALL status='sent' - zero pending, zero sending - so the */5 cron job is provably making ZERO calls at present. net._http_response holds 5 rows across the retained window (oldest 2026-09-11 11:00:00.308Z, newest 16:21:50Z): FIVE fires in that window from all callers combined. A cadence-derived figure would have been 288/day from */5 alone before adding the http_get jobs. Measured is 5 in ~6h. My earlier write-up's 'on every fire' carried the cadence implication and was an unmeasured upper bound. ATTRIBUTION BOUNDED, not claimed: _http_response has no url column and the matching queue rows are gone, so rows cannot be attributed to jobs. One suggestive alignment only - cron job 15 is '0 11 * * *' and the oldest retained row is 11:00:00.308Z; inference, not measurement. What IS established is a NEGATIVE: the drain cannot be among those 5 while the outbox holds no pending or stale-sending row. SEVERITY IS UNCHANGED AND THE LOW NUMBER MUST NOT BE READ AS MITIGATION. The grant is the exposure, not the cadence. A bearer transits a PUBLIC-readable queue whenever it transits at all, and one transit suffices for anyone polling. The quiet outbox is a property of TODAY'S TRAFFIC, not of the system: the same code under real email load fires a wake on every qualifying enqueue statement, and the gate that makes it quiet today is a DATA CONDITION, not a control. Separately, the response half is six-hour retention BY CONFIGURATION and is not flight-time regardless of fire count - 5 rows sitting up to 6h is the same PUBLIC-readable exposure whether it was 5 fires or 500. RUNNING TALLY OF MY OWN NARROW INSTRUMENTS ON THIS ROW, kept because the pattern is the lesson: nspacl pattern-matched for '=U' (missed PUBLIC and four named grants as independent paths); callers scoped to cron.job (missed the enqueue trigger); queue row count read without the ttl (missed six-hour response retention); and cadence read from the schedule without reading the guard (overstated transits ~50x). Four widenings, four findings. The still-unseen item remains callers OUTSIDE the database - coder-mars-cc's src/ grep, assigned with VENUS-350 stated.
-
FIFTH WIDENING DONE, AND PLUTO'S ATTRIBUTION METHOD WORKS HERE - WHICH CORRECTS A NEGATIVE I ASSERTED TWICE TODAY. db-mars-cc 2026-09-11, read-only, no values read. EVENT TRIGGERS: SIX on this ref, same count as pluto. issue_graphql_placeholder (sql_drop), issue_pg_cron_access, issue_pg_graphql_access, issue_pg_net_access, pgrst_ddl_watch (all ddl_command_end except the last pair), pgrst_drop_watch (sql_drop). All owned by supabase_admin, all evtenabled='O'. EXACTLY ONE names net.http_ in its function body: issue_pg_net_access -> extensions.grant_pg_net_access, which is the version-gated helper already on this row - so the event-trigger layer introduces NO new pg_net caller. THE NEGATIVE STATED EXPLICITLY as asked: no event trigger on this ref calls net.http_* other than the grant helper, and none re-grants on DDL because that helper's version gate (extversion IN '0.2'..'0.11.0', ref runs 0.20.0) means it never fires. Consistent with the earlier pg_default_acl finding of zero rows for schema net: a fix here would not silently undo itself on object recreation. *** ATTRIBUTION IS POSSIBLE AND I WAS WRONG TO SAY IT WAS NOT. *** I twice recorded 'no url column, matching queue rows gone, therefore unattributable'. db-pluto-cc correlated against the SOURCE table instead of the queue and it works on Mars too. Of the 5 retained responses, FOUR land within 2 seconds of an emailOutbox insert (deltas 85ms, ~10ms, ~10ms, 80ms) and exactly 4 outbox rows exist in that window - a 1:1 match. The fifth (id 104, 2026-09-11 11:00:00.308Z) correlates with ZERO outbox inserts and sits on a 5-minute boundary, matching cron job 15 ('0 11 * * *'). So the retained window decomposes as 4 enqueue-TRIGGER fires + 1 daily cron fire. THAT ALSO FALSIFIES MY OWN 'ESTABLISHED NEGATIVE' FROM THE PREVIOUS ENTRY, and the error is worth more than the correction. I wrote: 'the drain cannot be among those 5 while the outbox holds no pending or stale-sending row.' Wrong. I read the CURRENT state of emailOutbox (560 rows, all 'sent', zero pending) and inferred backwards about fires that had already happened - but those rows WERE pending at insert time, the trigger woke the drain, mail was sent, and status became 'sent' AS A RESULT OF THE VERY FIRE I WAS LOOKING FOR. A state table whose state is changed by the event under investigation cannot be read as evidence about that event's absence. The drain was not idle; it was successful, which looks identical to idle in an end-state snapshot. CORRECTED PROFILE FOR THIS REF: bearer transits track EMAIL VOLUME, not cron cadence. In the ~5h21m retained window, 4 of 5 fires came from the enqueue trigger and 1 from daily cron; the */5 job contributed zero, because by the time it ticks the trigger has already drained the row. Under real email load the trigger fires per qualifying enqueue STATEMENT, so transits scale with outbound mail. SEVERITY UNCHANGED, and this arguably raises the practical exposure rather than lowering it: the transit count is driven by a business quantity that grows, not by a fixed schedule anyone could reason about from cron. Running tally of my narrow instruments on this row is now FIVE: nspacl grepped for '=U'; callers scoped to cron.job; queue count read without the ttl; cadence read from the schedule without the guard; and attribution declared impossible from the queue side without trying the source side. Every widening found something, and the fifth was handed to me by another ref rather than found here.
-
Severity premise changed, 2026-09-11. ELAZAR DIRECTIVE relayed by pmmaster-evolutiva-cc (eq#108): settle the pg_net PUBLIC-ACL question with measurement, not with PUBLIC-reachability theory - his words, 'we dont use public and anon and data api, none of that matters to us, check'. The pg_net caller-enumeration work is superseded and stopped; it was never the bound. Measured on mars, read-only: GET /v1/projects/ustenjufophwhlkzfdso/postgrest returns db_schema = "" (empty string) - NO schema is exposed to PostgREST, not net and not public; db_extra_search_path is 'public, extensions', max_rows 1000. An anon key exists but is not shipped: grep for NEXT_PUBLIC_SUPABASE_ANON_KEY / SUPABASE_ANON_KEY across src/ returns zero hits, and the three browser clients (src/app/login/login-client.tsx:13, src/app/login/login-button.tsx, src/components/app-sidebar.tsx:213) all pass NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY and are Supabase AUTH only - every data call is server-side over pg. Live probe with the revealed publishable key, because 'config says off' and 'actually unreachable' are different claims: /rest/v1/ root -> 401, /rest/v1/http_request_queue with Accept-Profile: net -> PGRST002, /rest/v1/users on public -> PGRST002. So PUBLIC-holds-INSERT on net is an internal-role issue only, with no browser-reachable path. pmmaster owns the severity call; this row records the measurement, not a disposition. MARS-712 remains blocked on Elazar for the REVOKE FROM PUBLIC paired with GRANT EXECUTE ON net.http_post/net.http_get TO postgres in ONE operation - that pairing requirement is unchanged by this finding, only its urgency is.
-
db03-mars-ca
-
Read-only research by coder03-mars-ca: MARS-712 is real, not LLM-only. Mars-local migration 135 removed mars_app_runtime extension USAGE; six Mars pg_net consumers remain postgres-owned guarded outbox/cron paths. A bare PUBLIC revoke would break those callers, while project postgres cannot alter Supabase-owned ACLs. Remaining decision is Supabase support for atomic PUBLIC revoke plus least-required postgres grants, or explicit risk acceptance. Source plus prior recorded live measurement only; current MCP account cannot freshly query Mars. No BWI status change or DB mutation.
-
db-mars-ca / db
-
2026-09-28 ownership review: prior measured evidence and blockedReason reviewed; no fresh production query or ACL mutation. Decision remains Elazar's: (A) ask Supabase support to atomically REVOKE EXECUTE on net.* from PUBLIC and GRANT only the required net.http_post/net.http_get signatures to postgres (including the explicitly measured net schema/table/sequence exposure in support scope), validating the full operational caller set; or (B) explicitly accept the measured risk and close as accepted-risk. Do not run a bare revoke or attempt self-service ACL changes: postgres cannot change the Supabase-owned ACLs, and naive revoke breaks live postgres-owned pg_net jobs. Status remains blocked pending that decision.
-
pmmaster 2026-10-06: independently re-confirmed on the shared terra/enamel ref by db-enamel-ca via TERRA-262, by a different route (role-privilege census from a signup-burst investigation, not a proacl scan). Same upstream cause, same blocked remediation. ESCALATION: on that ref the holder is 'authenticated' - every completed Google sign-in - not a credentialed login role, so the exposed population is larger than the thirteen roles measured here. One unmeasured term decides whether it is live: whether net is an exposed Data API schema. Consolidated with TERRA-257 and TERRA-262 into ONE Elazar ask rather than three parked rows.
-
pmmaster 2026-10-06: TERRA-262's Data API term measured NO - net is not PostgREST-exposed on the shared terra/enamel ref, so my escalation that 'authenticated' gave a larger REACH than the thirteen roles here is RETRACTED. The larger population exists but has no observed route. This row remains the real present-day exposure of the pair, because a credentialed login role reaches net over a DB connection and never needs the Data API. Urgency: file-a-ticket, not incident. Remediation unchanged and still Elazar's call.
-
db-mars-cc / db