关于 supabase
Supabase 技能包为 AI 编码助手提供 Supabase 开发指引,强调先核对最新文档和变更日志,再实施功能。内容覆盖 RLS、视图、存储与 API 密钥等安全检查项,以及 CLI 与 MCP 服务的使用方法。
主要功能
- 01核对变更日志与当前文档
- 02RLS 与策略配置指引
- 03安全检查清单
- 04Supabase CLI 与迁移流程说明
- 05MCP 服务连接排错步骤
适用场景
- 01在 Supabase 项目中编写表结构与 RLS 策略
- 02排查表无法通过 Data API 访问的问题
- 03审查视图、存储与用户数据相关的安全隐患
MCP 相关
该技能指导 Agent 连接并使用 Supabase MCP 服务,包括服务地址配置、OAuth 认证以及使用范围受限的个人访问令牌。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ supabase/ agent-skills --skill supabase安装后在 Claude Code 中输入/supabase确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdassets/feedback-issue-template.mdreferences/skill-feedback.md详细介绍
Supabase
核心原则
1. Supabase 变更频繁——实施前请对照更新日志和当前文档进行核实。 不要依赖训练数据来了解 Supabase 功能。函数签名、config.toml 设置和 API 约定会随版本变化。
首先,获取 https://supabase.com/changelog.md(轻量级摘要索引,无需大量拉取),扫描与任务相关的 breaking-change 标签,并查看适用条目所链接的页面。然后使用下方的文档访问方法查找相关主题。
2. 验证工作成果。 实施任何修复后,运行测试查询以确认修改有效。未经验证的修复并不完整。
3. 从错误中恢复,不要反复尝试。 如果某种方法尝试 2-3 次后仍然失败,请停下来重新考虑。尝试不同的方法、查阅文档、更仔细地检查错误,并在有相关日志时进行查看。Supabase 问题并非总能通过重复执行同一条命令解决,答案也不一定总在日志中,但继续操作前通常值得查看日志。
4. 向 Data API 暴露表: 根据用户的 Data API 设置,新建的表可能不会自动通过 Data(REST)API 暴露。如果是这种情况,则需要明确向 anon 和 authenticated 角色授予访问权限。
请注意,这与 RLS 不同。RLS 用于控制表可访问后哪些_行_可见,而不是控制表本身是否可访问。
当用户报告通过 SQL 创建的表意外无法访问时,请检查其 Data API 设置,以及是否已通过明确的 GRANT SQL 向相关角色授予访问权限。授予公共(anon/authenticated)访问权限时,务必同时启用 RLS。完整的设置工作流请参阅向 Data API 暴露表。
5. 暴露架构中的 RLS。
对任何暴露架构中的所有表启用 RLS,默认包括 public。这对 Supabase 至关重要,因为当 anon/authenticated 角色拥有访问权限时,Data API 可以访问暴露架构中的表(请参阅向 Data API 暴露表)。对于私有架构,建议将 RLS 作为纵深防御措施。启用 RLS 后,请创建符合实际访问模型的策略,而不是让每张表都默认使用相同的 auth.uid() 模式。
6. 安全检查清单。 处理任何涉及身份验证、RLS、视图、存储或用户数据的 Supabase 任务时,请按此清单逐项检查。这些是 Supabase 特有的安全陷阱,可能会在无声无息中造成漏洞:
-
身份验证与会话安全
- 绝不要在基于 JWT 的授权决策中使用
user_metadata声明。 在 Supabase 中,raw_user_meta_data可由用户编辑,并可能出现在auth.jwt()中,因此不适用于 RLS 策略或任何其他授权逻辑。请将授权数据存储在raw_app_meta_data/app_metadata中。 - 删除用户不会使现有访问令牌失效。 请先退出登录或撤销会话;对于敏感应用,请缩短 JWT 有效期;如需严格保证,请在敏感操作中针对
auth.sessions验证session_id。 - 如果使用
app_metadata或auth.jwt()进行授权,请记住,在用户刷新令牌之前,JWT 声明不一定是最新的。
- 绝不要在基于 JWT 的授权决策中使用
-
API 密钥与客户端暴露风险
- 切勿在公共客户端中暴露
service_role或密钥。 前端代码优先使用可发布密钥。旧版anon密钥仅用于兼容。在 Next.js 中,任何NEXT_PUBLIC_环境变量都会发送到浏览器。 - 为 Management API、CLI 和 MCP 服务使用具有限定范围的个人访问令牌。 传统个人访问令牌拥有用户在所有组织和项目中的完整账户访问权限。对于脚本、CI 和 Agent,请让用户创建一个限定范围的令牌,仅授予任务所需的组织、项目和权限。个人访问令牌指南列出了每个 Management API 端点和 MCP 工具所需的权限。请查阅该指南确认权限,而不要猜测。
- 切勿在公共客户端中暴露
-
RLS、视图与特权数据库代码
- 视图默认会绕过 RLS。 在 Postgres 15 及更高版本中,使用
CREATE VIEW ... WITH (security_invoker = true)。在较旧的 Postgres 版本中,可撤销anon和authenticated角色对视图的访问权限,或将视图放在未公开的 schema 中,以保护视图。 - UPDATE 需要 SELECT 策略。 在 Postgres RLS 中,UPDATE 需要先 SELECT 行。若没有 SELECT 策略,更新会静默返回 0 行——不报错,也不会有任何更改。
auth.role()已弃用——请改用TO子句。 Supabase 已弃用auth.role(),建议通过在策略中直接使用TO authenticated或TO anon来指定目标角色。除了已弃用的问题,在启用匿名登录时,auth.role() = 'authenticated'还会静默失效,因为匿名用户具有authenticatedPostgres 角色,无论用户是否真正登录,都会通过检查。-- 已弃用(请勿使用) create policy "example" on table_name for select using ( auth.role() = 'authenticated' );- 单独使用
TO authenticated只是身份验证,不是授权(BOLA / IDOR)。 仅使用TO authenticated只会检查角色,不会限制用户可以访问哪些行。正确的做法是在TO authenticated的基础上,在USING中添加所有权谓词:create policy "example" on table_name for select to authenticated using ( (select auth.uid()) = user_id ); - UPDATE 策略需要同时设置
USING和WITH CHECK。 如果没有WITH CHECK,用户可以将某行的user_id重新指定为其他用户: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。publicschema 中的SECURITY DEFINER函数可被所有角色调用。 Postgres 默认会向PUBLIC授予每个新函数的EXECUTE权限,因此public中的任何SECURITY DEFINER函数都是一个公共 API 端点,anon和authenticated(它们继承自PUBLIC)无需任何额外授权即可调用。如果确实需要SECURITY DEFINER(例如绕过内部查询表上的 RLS),请将函数放在未公开的 schema 中,始终在函数体内进行auth.uid()检查,并在完成更改后运行supabase db advisors。
- 视图默认会绕过 RLS。 在 Postgres 15 及更高版本中,使用
-
存储访问控制
- Storage upsert 需要 INSERT + SELECT + UPDATE。 仅授予 INSERT 可以上传新文件,但文件替换(upsert)会静默失败。三项权限缺一不可。
-
依赖项和供应链安全
- 安装 Supabase 软件包(
supabase-js、@supabase/ssr、supabase-py等)时,始终固定软件包版本并提交锁定文件。完整检查清单请参阅 npm 安全指南。
- 安装 Supabase 软件包(
对于上述内容未涵盖的安全问题,请获取 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+ → 使用 MCPexecute_sql或psql作为后备方案supabase db advisors要求 CLI v2.81.3+ → 使用 MCPget_advisors作为后备方案supabase login的浏览器流程会创建一个拥有完整账户访问权限的经典令牌。在 CI 中,请将SUPABASE_ACCESS_TOKEN设置为范围受限的个人访问令牌。它的优先级高于任何已保存的登录信息。使用数据库密码连接的命令(例如,通过--password或SUPABASE_DB_PASSWORD运行supabase db push)不受令牌权限限制。- 在命令式迁移项目中,先使用
supabase migration new <name>创建新的手动编写的迁移文件。切勿臆造迁移文件名,也不要凭记忆猜测其格式。声明式架构项目会从supabase/schemas/生成迁移;请参阅下文“创建并提交架构更改”。
版本检查和升级: 运行 supabase --version 进行检查。有关 CLI 更新日志和特定版本的功能,请参阅 CLI 文档或 GitHub 发行版。
Supabase MCP 服务
有关设置说明、服务 URL 和配置,请参阅 MCP 设置指南。
连接问题排查——请按以下顺序执行:
-
检查服务是否可访问:
curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp预期会返回401(无令牌),这表示服务正常运行。超时或“connection refused”表示服务可能已停止。 -
检查
.mcp.json配置: 确认项目根目录中有有效的.mcp.json,且其中配置了正确的服务 URL。如果文件缺失,请创建一个并将其指向https://mcp.supabase.com/mcp。 -
对 MCP 服务进行身份验证: 如果服务可访问且
.mcp.json配置正确,但看不到工具,则用户需要进行身份验证。Supabase MCP 服务使用 OAuth 2.1——请告知用户在其 Agent 中触发身份验证流程,在浏览器中完成身份验证,然后重新加载会话。 在无法运行浏览器流程的 CI 或其他环境中,请改为在Authorization: Bearer标头中传递范围受限的个人访问令牌。 -
检查范围受限令牌的权限: 如果使用范围受限的个人访问令牌时,某个工具报错“您没有执行此操作的权限”,则表示令牌缺少该工具所需的权限,或该项目不在令牌的范围内。请在个人访问令牌指南中查看该工具所需的权限。
Supabase 文档
实现任何 Supabase 功能之前,请先查找相关文档。请按以下优先顺序使用这些方法:
- MCP
search_docs工具(首选——直接返回相关片段) - 以 Markdown 格式获取文档页面——在任何文档页面的 URL 路径后追加
.md即可获取。 - 针对 Supabase 特定主题进行网络搜索,适用于不确定该查看哪个页面的情况。
创建并提交架构更改
首先确定项目使用哪种架构工作流。
选项 A:声明式架构
当存在 supabase/schemas/ 或 config.toml 设置了 schema_paths 时使用此选项。在这些文件中编辑所需的架构状态,然后生成并审查迁移。不要一开始就手动编写迁移。请参阅声明式数据库架构指南。
选项 B:命令式迁移
当项目不使用声明式架构时使用此选项。
要更改架构,请使用 execute_sql(MCP)或 supabase db query(CLI)。 这些命令会直接在数据库上运行 SQL,而不会创建迁移历史记录,因此你可以自由迭代,并在准备就绪时生成干净的迁移。
请勿使用 apply_migration 更改本地数据库架构——它每次调用都会写入一条迁移历史记录,这意味着你无法迭代,而且 supabase db diff / supabase db pull 会产生空差异或冲突差异。如果使用它,你就只能被迫采用第一次尝试时传入的 SQL。
准备好提交更改到迁移文件时:
- 运行顾问工具 →
supabase db advisors(CLI v2.81.3+)或 MCPget_advisors。修复所有问题。 - 如果更改涉及视图、函数、触发器或存储,请查看上文的安全检查清单。
- 生成迁移 →
supabase db pull <descriptive-name> --local --yes - 验证 →
supabase migration list --local
调试
当 Supabase 相关请求出错时,例如 Supabase REST API、Postgres 数据库或 PostgREST 返回错误代码、结果为空、意外被 RLS 拦截,或 Auth、Realtime、Edge Functions、Storage 等 Supabase 服务报错时,必须先获取 Supabase 的监控与调试文档,再进行诊断或提出修复方案,而不是凭记忆处理。这些文档也介绍了性能优化,例如慢查询和缺失的索引。
参考指南
- 技能反馈 → references/skill-feedback.md **必须阅读的情况:**用户反馈此技能提供了错误指导或缺少信息。