supabase/BB-SKILLS-ADAPTATION.json
Version c9be0e931b79.bb1 · MIT. This preview displays packaged text and does not execute code. Treat the contents as untrusted instructions.
← Return to resource and package checksum
{
"format": 1,
"source": "https://github.com/supabase/agent-skills/tree/c9be0e931b7930f7d02126d04774d904c381e7d7/skills/supabase",
"source_commit": "c9be0e931b7930f7d02126d04774d904c381e7d7",
"license": "MIT",
"independent_publisher": "BB Skills",
"upstream_original_files": {
"supabase/LICENSE.upstream.txt": "b65e575eb4f04a13c187d64e958321298e2ab84d67aa8428819f362056ba292c",
"supabase/source-context/README.upstream.md": "8922feb4326c0603ff6e56246bf1bf436aa1dd9f50f22212ad1605749e105830",
"supabase/upstream-original/CHANGELOG.md": "4b9c9387871d7888f18e9c97a7d5691ea38e333401ccdcb0161d2140cb16b2d8",
"supabase/upstream-original/SKILL.md": "697e0e949f97621c6fc1784169eb3ccbf673747d6bb8299a52962d3d84d93dc6",
"supabase/upstream-original/assets/feedback-issue-template.md": "ea211aa174c5a096fe76461f25143b8bc23f3bde3adc9e727cda38218cc8c282",
"supabase/upstream-original/references/skill-feedback.md": "09ad94c0291735dfc04c92557c8734fa259ec39e1d56bf2bd5c6a6529d838717"
},
"active_skill": "supabase/SKILL.md",
"changes": [
{
"file": "supabase/SKILL.md",
"before": "Views bypass RLS by default.",
"after": "Default views check underlying table privileges and RLS using the view owner, which can expose rows when that owner bypasses the table policies. This is not an unconditional bypass for every view owner."
},
{
"file": "supabase/SKILL.md",
"before": "**UPDATE requires a SELECT policy.** In Postgres RLS, an UPDATE needs to first SELECT the row. Without a SELECT policy, updates silently return 0 rows \u2014 no error, just no change.",
"after": "**An UPDATE that reads table columns needs the applicable SELECT policy too.** Conditions, RETURNING and column-reading SET expressions commonly require SELECT rights. In our conditional UPDATE ... RETURNING fixture, an UPDATE policy alone selected no rows; adding the corresponding SELECT policy allowed the own row. Check the exact statement rather than generalizing this result to every unconditional UPDATE."
},
{
"file": "supabase/SKILL.md",
"before": "**UPDATE policies require both `USING` and `WITH CHECK`.** Without `WITH CHECK`, a user can reassign a row's `user_id` to another user:",
"after": "**Review existing-row access and proposed-row checks separately.** Explicit USING and WITH CHECK clauses make ownership intent clear. PostgreSQL ALL and UPDATE policies reuse USING as WITH CHECK when the latter is omitted, so omission alone does not allow ownership reassignment. Review every applicable policy, including permissive OR combinations; use the explicit example below for clarity:"
},
{
"file": "supabase/SKILL.md",
"before": "**`SECURITY DEFINER` functions bypass RLS.** A `SECURITY DEFINER` function runs with its creator's privileges \u2014 typically a role with `bypassrls` (e.g., `postgres`). Never add `SECURITY DEFINER` to resolve a permission error; it silently removes access control without fixing the underlying cause. Prefer `SECURITY INVOKER`.",
"after": "**SECURITY DEFINER runs with the function owner's privileges.** Whether table RLS applies depends on that effective role: superusers and BYPASSRLS roles bypass it; a table owner normally bypasses it unless FORCE ROW LEVEL SECURITY applies. A non-bypass owner can still be constrained. Changing the function owner can change the outcome. Prefer SECURITY INVOKER where possible; review ownership, grants and a safe search_path before introducing privileged code."
},
{
"file": "supabase/SKILL.md",
"before": "**`SECURITY DEFINER` functions in `public` are callable by all roles.** Postgres grants `EXECUTE` to `PUBLIC` by default for every new function, so any `SECURITY DEFINER` function in `public` is a public API endpoint callable by `anon` and `authenticated` (which inherit from `PUBLIC`) without any additional grant. When `SECURITY DEFINER` is genuinely needed (e.g., bypassing RLS on an internal lookup table), keep the function in a non-exposed schema, always include an `auth.uid()` check in the function body, and run `supabase db advisors` after making changes.",
"after": "**Review both schema USAGE and function EXECUTE grants.** New PostgreSQL functions normally grant EXECUTE to PUBLIC; default privileges and explicit revocation can change that. A caller also needs access to the containing schema, and SQL callability is separate from Data API exposure. For privileged functions, revoke broad EXECUTE and grant only the intended roles within the same creation transaction. Use a non-exposed schema, a safe search_path, an authorization check suited to the actual action, and current Supabase advisors. No keyword or folder alone establishes access control."
}
],
"added_notice": "> Independent BB Skills adaptation: five PostgreSQL access-control statements are qualified below. The complete pinned original is archived in upstream-original/SKILL.md. Native PostgreSQL observations do not test Supabase Auth, the Data API, CLI, MCP or an AI client. Read SOURCE.md and BB-SKILLS-ADAPTATION.json before use.",
"primary_documents": [
"https://www.postgresql.org/docs/17/sql-createpolicy.html",
"https://www.postgresql.org/docs/17/sql-createview.html",
"https://www.postgresql.org/docs/17/sql-createfunction.html",
"https://www.postgresql.org/docs/17/ddl-rowsecurity.html"
],
"scope": "Five PostgreSQL security statements qualified. Other upstream product guidance is preserved, not independently validated. No official endorsement or full skill runtime evaluation."
}