
supabase
熱門當執行任何涉及 Supabase 的任務時使用。觸發條件:Supabase 產品(Database、Auth、Edge Functions、Realtime、Storage、Vectors、Cron、Queues);客戶端函式庫與 SSR 整合(supabase-js、@supabase/ssr)在 Next.js、React、SvelteKit、Astro、Remix 中;驗證問題(登入、登出、session、JWT、cookie、getSession、getUser、getClaims、RLS);Supabase CLI 或 MCP 伺服器;schema 變更、遷移、安全稽核、Postgres 擴充套件(pg_graphql、pg_cron、pg_vector)。
當執行任何涉及 Supabase 的任務時使用。觸發條件:Supabase 產品(Database、Auth、Edge Functions、Realtime、Storage、Vectors、Cron、Queues);客戶端函式庫與 SSR 整合(supabase-js、@supabase/ssr)在 Next.js、React、SvelteKit、Astro、Remix 中;驗證問題(登入、登出、session、JWT、cookie、getSession、getUser、getClaims、RLS);Supabase CLI 或 MCP 伺服器;schema 變更、遷移、安全稽核、Postgres 擴充套件(pg_graphql、pg_cron、pg_vector)。
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 設定,新建立的資料表可能不會自動透過 Data (REST) API 暴露。若發生此情況,需要明確授予 anon 與 authenticated 角色存取權限。
請注意,這與 RLS 不同,RLS 控制的是資料表可存取後哪些_資料列_可見,而非資料表本身是否可存取。
當使用者回報 SQL 建立的資料表意外無法存取時,請檢查其 Data API 設定,以及角色是否已透過明確的 GRANT SQL 獲得存取權限。授予公開(anon/authenticated)存取權限時,務必同時啟用 RLS。完整設定流程請參閱將資料表暴露給 Data API。
5. 暴露 schema 中的 RLS。
在任何暴露的 schema(預設包含 public)中的每個資料表上啟用 RLS。這在 Supabase 中至關重要,因為當 anon/authenticated 角色擁有存取權限時,暴露 schema 中的資料表可透過 Data API 存取(請參閱將資料表暴露給 Data API)。對於私有 schema,建議將 RLS 作為深度防禦。啟用 RLS 後,建立符合實際存取模型的政策,而非讓每個資料表都使用相同的 auth.uid() 模式。
6. 安全檢查清單。
在處理任何涉及 auth、RLS、view、儲存或使用者資料的 Supabase 任務時,請執行此檢查清單。這些是 Supabase 特有的安全陷阱,會默默產生漏洞:
-
Auth 與 session 安全
- 切勿在基於 JWT 的授權決策中使用
user_metadata宣告。 在 Supabase 中,raw_user_meta_data可由使用者編輯,且可能出現在auth.jwt()中,因此不適合用於 RLS 政策或任何其他授權邏輯。請改用raw_app_meta_data/app_metadata儲存授權資料。 - 刪除使用者不會使現有的存取 token 失效。 請先登出或撤銷 session,對敏感應用程式保持較短的 JWT 過期時間,並在嚴格要求下,對敏感操作驗證
session_id與auth.sessions。 - 若使用
app_metadata或auth.jwt()進行授權,請記住 JWT 宣告在使用者 token 刷新前不一定是最新的。
- 切勿在基於 JWT 的授權決策中使用
-
API 金鑰與客戶端暴露
- 切勿在公開客戶端中暴露
service_role或 secret key。 前端程式碼請優先使用 publishable key。舊版anon金鑰僅供相容性使用。在 Next.js 中,任何NEXT_PUBLIC_環境變數都會傳送至瀏覽器。
- 切勿在公開客戶端中暴露
-
RLS、view 與特權資料庫程式碼
- View 預設繞過 RLS。 在 Postgres 15 及以上版本,使用
CREATE VIEW ... WITH (security_invoker = true)。在較舊版本的 Postgres 中,請撤銷anon與authenticated角色對 view 的存取權限,或將其置於未暴露的 schema 中來保護 view。 - 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。public中的SECURITY DEFINER函式可由所有角色呼叫。 Postgres 預設對每個新函式授予PUBLIC的EXECUTE權限,因此public中的任何SECURITY DEFINER函式都是一個公開 API 端點,可由anon與authenticated(繼承自PUBLIC)呼叫,無需額外授權。當確實需要SECURITY DEFINER時(例如繞過內部查詢資料表的 RLS),請將函式保留在未暴露的 schema 中,務必在函式本體中加入auth.uid()檢查,並在變更後執行supabase db advisors。
- View 預設繞過 RLS。 在 Postgres 15 及以上版本,使用
-
儲存存取控制
- 儲存 upsert 需要 INSERT + SELECT + UPDATE。 僅授予 INSERT 允許新上傳,但檔案取代(upsert)會默默失敗。你需要三者皆備。
-
相依性與供應鏈安全
- 安裝 Supabase 套件(
supabase-js、@supabase/ssr、supabase-py等)時,務必鎖定套件版本並提交 lockfile。 完整檢查清單請參閱 npm 安全指南。
- 安裝 Supabase 套件(
若上述未涵蓋任何安全疑慮,請擷取 Supabase 產品安全索引:https://supabase.com/docs/guides/security/product-security.md
Supabase CLI
務必透過 --help 探索指令 — 切勿猜測。CLI 結構在不同版本間可能有所變更。
supabase --help # 所有頂層指令
supabase <group> --help # 子指令(例如 supabase db --help)
supabase <group> <command> --help # 特定指令的旗標
Supabase CLI 已知陷阱:
supabase db query需要 CLI v2.79.0+ → 請改用 MCPexecute_sql或psql作為備援supabase db advisors需要 CLI v2.81.3+ → 請改用 MCPget_advisors作為備援- 當你需要新的遷移 SQL 檔案時,務必先使用
supabase migration new <name>建立。切勿自行發明遷移檔名或依賴記憶中的預期格式。
版本檢查與升級: 執行 supabase --version 檢查。如需 CLI 變更日誌與版本特定功能,請參閱 CLI 文件 或 GitHub 發行頁面。
Supabase MCP 伺服器
設定說明、伺服器 URL 與組態,請參閱 MCP 設定指南。
連線問題疑難排解 — 請依序執行以下步驟:
-
檢查伺服器是否可連線:
curl -so /dev/null -w "%{http_code}" https://mcp.supabase.com/mcp
預期會收到401(無 token),表示伺服器正常運作。逾時或「連線被拒絕」則表示可能已關閉。 -
檢查
.mcp.json組態:
確認專案根目錄有有效的.mcp.json,且包含正確的伺服器 URL。若缺少,請建立一個指向https://mcp.supabase.com/mcp的檔案。 -
驗證 MCP 伺服器:
若伺服器可連線且.mcp.json正確,但工具仍不可見,則使用者需要進行驗證。Supabase MCP 伺服器使用 OAuth 2.1 — 請告知使用者在他們的 agent 中觸發驗證流程,在瀏覽器中完成驗證,然後重新載入 session。
Supabase 文件
在實作任何 Supabase 功能前,請先找到相關文件。請依優先順序使用以下方法:
- MCP
search_docs工具(優先 — 直接回傳相關片段) - 以 markdown 格式擷取文件頁面 — 任何文件頁面皆可透過在 URL 路徑後加上
.md來擷取。 - 針對 Supabase 特定主題進行網路搜尋,當你不知道該查閱哪個頁面時。
建立與提交 Schema 變更
若要進行 schema 變更,請使用 execute_sql(MCP)或 supabase db query(CLI)。 這些指令會直接在資料庫上執行 SQL,而不會建立遷移歷史記錄,因此你可以自由迭代,並在準備好時產生乾淨的遷移。
請勿使用 apply_migration 來變更本地資料庫 schema — 它每次呼叫都會寫入遷移歷史記錄,這意味著你無法迭代,且 supabase db diff / supabase db pull 會產生空白或衝突的 diff。若使用它,你將被困在第一次嘗試時傳入的任何 SQL 中。
準備好提交變更至遷移檔案時:
- 執行 advisors →
supabase db advisors(CLI v2.81.3+)或 MCPget_advisors。修正任何問題。 - 檢閱上述安全檢查清單,若你的變更涉及 view、函式、觸發器或儲存。
- 產生遷移 →
supabase db pull <descriptive-name> --local --yes - 驗證 →
supabase migration list --local
參考指南
- 技能回饋 → references/skill-feedback.md
必須閱讀當使用者回報此技能提供了錯誤指引或遺漏資訊時。





