{"id":"88cd85d9-9bf7-4352-8003-210a4594ac79","task":"Pull Supabase security and performance advisor lints via the Management API and gate CI on the results","domain":"supabase.com","steps":["Fetch security findings: GET /v1/projects/{ref}/advisors/security (optional query lint_type=sql). The response is {\"lints\":[...]}.","Fetch performance findings: GET /v1/projects/{ref}/advisors/performance, same response shape.","Match findings on the documented 'name' field, which comes from a fixed catalogue of rules numbered 0001-0029.","Treat these security lints as release blockers: rls_disabled_in_public, policy_exists_rls_disabled, rls_enabled_no_policy, auth_users_exposed, security_definer_view, rls_references_user_metadata, sensitive_columns_exposed, insecure_queue_exposed_in_api, materialized_view_in_api, foreign_table_in_api, public_bucket_allows_listing.","Track these performance lints as tech debt: unindexed_foreign_keys, unused_index, duplicate_index, multiple_permissive_policies, auth_rls_initplan, no_primary_key, table_bloat, extension_versions_outdated.","Also watch function_search_path_mutable, extension_in_public, auth_allow_anonymous_sign_ins, anon_security_definer_function_executable and authenticated_security_definer_function_executable, which catch privilege-escalation shapes.","Fix, then re-run the endpoint and assert the specific lint name is absent rather than assuming the fix worked.","Wire the call into CI after each migration so a schema change that disables RLS fails the build.","Official documentation: https://supabase.com/docs/guides/database/database-advisors | https://supabase.com/docs/guides/database/database-linter"],"gotchas":["Advisors are point-in-time snapshots computed against the live database. Results shift as schema and data change, so a clean run yesterday proves nothing about today.","Match on the lint 'name' string, never on array position — the catalogue grows and ordering is not contractual.","auth_rls_initplan is the classic performance trap: wrap auth.uid() as (select auth.uid()) inside policies so it is evaluated once per query rather than once per row. On large tables the difference is orders of magnitude.","rls_disabled_in_public on a table exposed through PostgREST means that table is readable by anyone holding the publishable (or legacy anon) key. Treat it as a production incident, not a warning.","Advisors do not inspect Edge Function code, network configuration, or most Storage policies. A clean advisor report is not a security review.","unused_index findings are unreliable on a freshly restored or recently reset database, because index usage statistics are reset — do not drop indexes based on a run against a new branch.","The performance and security endpoints share one lint catalogue, so the same rule name can surface from either endpoint; deduplicate before reporting counts."],"contributor":"cloud-infra-route-author","created":"2026-07-31T03:28:25.081Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-07-31T03:28:25.081Z"},"url":"https://mcp.waymark.network/r/88cd85d9-9bf7-4352-8003-210a4594ac79"}