返回技能市场
开发运维 安全

supabase

@admin/supabase

Use when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client libraries and SSR integrations (supabase-js, @supabase/ssr) in Next.js, React, SvelteKit, Astro, Remix; auth issues (login, logout, sessions, JWT, cookies, getSession, getUser, getClaims, RLS); Supabase CLI or MCP server; schema changes, migrations, declarative schemas, security audits, Postgres extensions (pg_graphql, pg_cron, pg_vector); debugging and troubleshooting errors or unexpected behavior on Supabase projects (HTTP errors, Postgres errors, RLS surprises, permission denied, schema cache issues, timeouts, Edge Function crashes, Realtime drops, Storage failures) and reading or querying logs (Logs Explorer, ClickHouse).

admin 热度 293v0.0.1

Supabase

核心原则

1. Supabase 经常变化——在实现之前,请对照 changelog 和当前文档进行验证。 不要依赖训练数据来处理 Supabase 功能。函数签名、config.toml 设置和 API 约定会在不同版本之间变化。

首先,获取 https://supabase.com/changelog.md(一个轻量级摘要索引——不是重型拉取),扫描与你的任务相关的 breaking-change 标签,并跟随适用的链接页面。然后使用下面的文档访问方法查找相关主题。

2. 验证你的工作。 实现任何修复后,运行一个测试查询以确认更改有效。未经过验证的修复是不完整的。

3. 从错误中恢复,不要循环。 如果一种方法在 2-3 次尝试后失败,停止并重新考虑。尝试不同方法,查看文档,更仔细地检查错误,并在可用时查看相关日志。Supabase 问题并不总是通过重试同一命令解决,答案也不总是在日志中,但在继续之前,日志通常值得检查。

4. 将表暴露给 Data API: 根据用户的 Data API settings,新创建的表可能不会自动通过 Data (REST) API 暴露。如果发生这种情况,anonauthenticated 角色需要被显式授予访问权限。

请注意,这与 RLS 不同;RLS 控制表可访问后哪些 _行_ 可见,而不是表是否可访问。

当用户报告通过 SQL 创建的表意外不可访问时,检查他们的 Data API 设置,以及是否通过显式 GRANT SQL 授予角色访问权限。当授予公共(anon/authenticated)访问权限时,始终同时启用 RLS。参见 Exposing a Table to the Data API 了解完整设置工作流。

5. 暴露 schema 中的 RLS。 在任何暴露 schema 中的每个表上启用 RLS,默认包括 public。这在 Supabase 中至关重要,因为当 anon/authenticated 角色有访问权限时,暴露 schema 中的表可以通过 Data API 访问(参见 Exposing a Table to the Data API)。对于私有 schema,优先将 RLS 作为纵深防御。启用 RLS 后,创建匹配实际访问模型的政策,而不是将每个表默认设置为相同的 auth.uid() 模式。

6. 安全检查清单。 在处理任何涉及 auth、RLS、视图、存储或用户数据的 Supabase 任务时,运行此检查清单。这些是 Supabase 特有的安全陷阱,会静默创建漏洞:

  • 认证与会话安全
  • 绝不在基于 JWT 的授权决策中使用 user_metadata claims。 在 Supabase 中,raw_user_meta_data 可由用户编辑,并可能出现在 auth.jwt() 中,因此对于 RLS 政策或任何其他授权逻辑都不安全。改为将授权数据存储在 raw_app_meta_data / app_metadata 中。
  • 删除用户不会使现有访问令牌失效。 先注销或撤销会话,为敏感应用保持较短的 JWT 过期时间,并且对于严格保证,在敏感操作中将 session_idauth.sessions 进行验证。
  • 如果你使用 app_metadataauth.jwt() 进行授权,请记住 JWT claims 在用户令牌刷新之前并不总是最新的。
  • API key 与客户端暴露
  • 绝不在公共客户端中暴露 service_role 或 secret key。 前端代码优先使用 publishable keys。旧版 anon keys 仅用于兼容性。在 Next.js 中,任何 NEXT_PUBLIC_ 环境变量都会发送到浏览器。
  • RLS、视图和特权数据库代码
  • 视图默认绕过 RLS。 在 Postgres 15 及更高版本中,使用 CREATE VIEW ... WITH (security_invoker = true)。在较旧版本的 Postgres 中,通过撤销 anonauthenticated 角色的访问权限,或将视图放在未暴露 schema 中来保护你的视图。
  • UPDATE 需要 SELECT 政策。 在 Postgres RLS 中,UPDATE 需要先 SELECT 行。如果没有 SELECT 政策,更新会静默返回 0 行——没有错误,只是没有更改。
  • auth.role() 已弃用——请改用 TO 子句。 Supabase 已弃用 auth.role(),改为在政策上直接使用 TO authenticatedTO anon 指定目标角色。除了弃用之外,当启用匿名登录时,auth.role() = 'authenticated' 会静默失效,因为匿名用户携带 authenticated Postgres 角色,并且无论用户是否真正登录都会通过检查。
  • ``sql -- Deprecated (do not use) create policy "example" on table_name for select using ( auth.role() = 'authenticated' ); ``

  • 单独使用 TO authenticated 是身份认证但没有授权(BOLA / IDOR)。 使用 TO authenticated 仅检查角色——它不会限制用户可以访问哪些行。正确模式将 TO authenticatedUSING 中的所有权谓词结合:
  • ``sql create policy "example" on table_name for select to authenticated using ( (select auth.uid()) = user_id ); ``

  • UPDATE 政策需要同时包含 USINGWITH CHECK 如果没有 WITH CHECK,用户可以将某行的 user_id 重新分配给另一个用户:
  • ``sql create policy "example" on table_name for update to authenticated using ( (select auth.uid()) = user_id ) with check ( (select auth.uid()) = user_id ); ``

  • SECURITY DEFINER 函数会绕过 RLS。 SECURITY DEFINER 函数以其创建者的特权运行——通常是具有 bypassrls 的角色(例如 postgres)。绝不要为了解决权限错误而添加 SECURITY DEFINER;它会静默移除访问控制,而没有修复根本原因。优先使用 SECURITY INVOKER
  • public 中的 SECURITY DEFINER 函数可被所有角色调用。 Postgres 默认对每个新函数向 PUBLIC 授予 EXECUTE,因此 public 中的任何 SECURITY DEFINER 函数都是一个公共 API 端点,anonauthenticated(它们继承自 PUBLIC)无需额外授权即可调用。当确实需要 SECURITY DEFINER 时(例如绕过内部查找表上的 RLS),将函数保留在非暴露 schema 中,始终在函数体中包含 auth.uid() 检查,并在进行更改后运行 supabase db advisors
  • 存储访问控制
  • Storage upsert 需要 INSERT + SELECT + UPDATE。 仅授予 INSERT 允许新上传,但文件替换(upsert)会静默失败。你需要全部三项。
  • 依赖与供应链安全
  • 在安装 Supabase 包时始终固定包版本并提交 lockfilessupabase-js@supabase/ssrsupabase-py 等)。参见 npm security guide 了解完整检查清单。

对于上面未涵盖的任何安全问题,获取 Supabase 产品安全索引:https://supabase.com/docs/guides/security/product-security.md

Supabase CLI

始终通过 --help 发现命令——绝不猜测。CLI 结构在不同版本之间会变化。

supabase --help                    # All top-level commands
supabase <group> --help            # Subcommands (e.g., supabase db --help)
supabase <group> <command> --help  # Flags for a specific command

Supabase CLI 已知陷阱:

  • supabase db query 需要 CLI v2.79.0+ → 使用 MCP execute_sqlpsql 作为回退
  • supabase db advisors 需要 CLI v2.81.3+ → 使用 MCP get_advisors 作为回退
  • 在命令式 migration 项目中,先使用 supabase migration new <name> 创建新的手写 migration 文件。绝不发明 migration 文件名或依赖记忆来猜测预期格式。声明式 schema 项目会从 supabase/schemas/ 生成 migrations;参见下面的 "Making and Committing Schema Changes"。

版本检查和升级: 运行 supabase --version 进行检查。对于 CLI changelogs 和特定版本功能,请查阅 CLI documentationGitHub releases

Supabase MCP Server

有关设置说明、服务器 URL 和配置,请参见 MCP setup guide

排查连接问题 — 按顺序执行以下步骤:

  1. 检查服务器是否可达:
  2. curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp 预期是 401(没有 token),这意味着服务器已启动。超时或 "connection refused" 表示它可能已宕机。

  1. 检查 .mcp.json 配置:
  2. 验证项目根目录中是否存在有效的 .mcp.json,并且服务器 URL 正确。如果缺失,创建一个指向 https://mcp.supabase.com/mcp 的配置。

  1. 对 MCP 服务器进行身份验证:
  2. 如果服务器可达且 .mcp.json 正确,但工具不可见,用户需要进行身份验证。Supabase MCP 服务器使用 OAuth 2.1 —— 告诉用户在他们的 agent 中触发 auth 流程,在浏览器中完成,并重新加载会话。

Supabase 文档

在实现任何 Supabase 功能之前,找到相关文档。按优先顺序使用这些方法:

  1. MCP search_docs 工具(优先——直接返回相关片段)
  2. 以 markdown 形式获取文档页面 — 任何文档页面都可以通过在 URL 路径后追加 .md 来获取。
  3. 当你不知道应该查看哪个页面时,对 Supabase 特定主题进行 web search

进行并提交 Schema 更改

首先决定项目使用哪种 schema 工作流。

选项 A:声明式 schemas

当存在 supabase/schemas/config.toml 设置了 schema_paths 时使用此方法。在这些文件中编辑所需的 schema 状态,然后生成并审查 migration。不要以手写 migration 开始。参见 Declarative database schemas guide

选项 B:命令式 migrations

当项目不使用声明式 schemas 时使用此方法。

要进行 schema 更改,请使用 execute_sql(MCP)或 supabase db query(CLI)。 这些会直接在数据库上运行 SQL,而不会创建 migration history 条目,因此你可以自由迭代,并在准备就绪时生成干净的 migration。

切勿使用 apply_migration 更改本地数据库 schema——它每次调用都会写入一个 migration history 条目,这意味着你无法迭代,并且 supabase db diff / supabase db pull 会产生空或冲突的 diffs。如果你使用它,你将被困在第一次尝试时传入的 SQL 上。

当准备提交你的更改到 migration 文件时:

  1. 运行 advisorssupabase db advisors(CLI v2.81.3+)或 MCP get_advisors。修复任何问题。
  2. 如果你的更改涉及视图、函数、触发器或存储,审查上面的安全检查清单
  3. 生成 migrationsupabase db pull <descriptive-name> --local --yes
  4. 验证supabase migration list --local

调试

当你在 Supabase 相关请求中收到错误时,例如来自 Supabase REST API、Postgres 数据库或 PostgREST 的错误代码、空结果、意外被 RLS 阻止,或来自 Auth、Realtime、Edge Functions 或 Storage 等 Supabase 服务的错误,你必须获取 Supabase 的 Monitoring and Debugging 文档,然后再进行诊断或提出修复方案,而不是凭记忆工作。同一文档也涵盖性能优化,例如慢查询和缺失索引。

参考指南

  • Skill Feedback → [references/skill-feedback.md](references/skill-feedback.md)
  • 必须阅读,当用户报告此 skill 给出了错误指导或缺少信息时。

qianwen skills install @admin/supabase