Skip to content

Commit e38ba62

Browse files
gregnrawaseem
andauthored
feat(ai): update rls knowledge for 'secure by default' (supabase#45072)
Updates the RLS knowledge loaded by the dashboard AI assistant to explain the new secure-by-default functionality. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Clarified PostgreSQL/RLS guidance in Studio: tables are now "secure by default"—SQL-created tables aren’t exposed via the Data API unless explicit grants are given to anon/authenticated/service_role and RLS is enabled; added an “Exposing a Table to the Data API” workflow, strengthened RLS prerequisites in best practices, and improved troubleshooting/error-recovery guidance. * **Tests / Evaluations** * Added an evaluation case validating guidance for non-RLS tables requiring explicit grants and RLS policies. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Ali Waseem <waseema393@gmail.com>
1 parent 9c0e9af commit e38ba62

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

apps/studio/evals/dataset.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,34 @@ export const dataset: AssistantEvalCase[] = [
141141
},
142142
metadata: { category: ['rls_policies'] },
143143
},
144+
{
145+
input: {
146+
prompt: "I have an orders table but now I can't query it through the API. What's wrong?",
147+
mockTables: {
148+
public: [
149+
{
150+
name: 'orders',
151+
rls_enabled: false,
152+
columns: [
153+
{ name: 'id', data_type: 'bigint' },
154+
{ name: 'user_id', data_type: 'uuid' },
155+
{ name: 'total', data_type: 'numeric' },
156+
],
157+
},
158+
],
159+
},
160+
},
161+
expected: {
162+
requiredKnowledge: ['rls'],
163+
correctAnswer:
164+
'The anon/authenticated roles may not have been granted access to the table. Check privileges and use GRANT to expose the table via the Data API.',
165+
},
166+
metadata: {
167+
category: ['rls_policies', 'debugging'],
168+
description:
169+
'Verifies the assistant identifies missing grants as the likely cause of an inaccessible table and guides the user to fix it',
170+
},
171+
},
144172
{
145173
input: { prompt: 'Write an edge function that sends a welcome email when a user signs up' },
146174
expected: {

apps/studio/lib/ai/prompts.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Row-Level Security (RLS) restricts which table rows are visible or modifiable by
1010
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
1111
\`\`\`
1212
- **Default Behavior:** Once enabled, all access is denied (except for the owner or superuser) until appropriate policies are defined.
13+
- **Secure by Default:** Depending on the user's [Data API settings](https://supabase.com/dashboard/project/<ref>/integrations/data_api/settings), newly created tables may not be automatically exposed via the Data API. If this is the case, \`anon\` and \`authenticated\` roles will need to be explicitly granted access. Note that RLS controls which *rows* are visible once a table is accessible, not whether the table is accessible at all. When a user reports a SQL-created table is unexpectedly inaccessible, check their Data API settings and whether the roles have been granted access via explicit \`GRANT\` SQL. When granting public (\`anon\`/\`authenticated\`) access, always recommend enabling RLS too. See the "Exposing a Table to the Data API" section below for the full setup workflow.
1314
1415
### Policy Types
1516
- **SELECT:** Use \`USING\` to filter visible rows on read.
@@ -129,6 +130,41 @@ CREATE POLICY "Tenant write" ON customers FOR INSERT TO authenticated WITH CHECK
129130
CREATE INDEX idx_customers_tenant ON customers(tenant_id);
130131
\`\`\`
131132
133+
## Exposing a Table to the Data API
134+
After creating a table that needs to be accessible via the Data API (PostgREST), follow these steps:
135+
136+
**Step 1 — Check existing privileges**
137+
\`\`\`sql
138+
SELECT grantee, privilege_type
139+
FROM information_schema.role_table_grants
140+
WHERE table_schema = 'public'
141+
AND table_name = 'your_table'
142+
AND grantee IN ('anon', 'authenticated', 'service_role');
143+
\`\`\`
144+
If the result is empty, the table has no API access. Proceed to step 2.
145+
146+
**Step 2 — Grant role privileges**
147+
\`\`\`sql
148+
-- anon: read-only public access
149+
GRANT SELECT ON public.your_table TO anon;
150+
-- authenticated: full CRUD (RLS policies will restrict which rows)
151+
GRANT SELECT, INSERT, UPDATE, DELETE ON public.your_table TO authenticated;
152+
-- service_role: full access, bypasses RLS
153+
GRANT ALL ON public.your_table TO service_role;
154+
\`\`\`
155+
Only grant the roles the table actually needs (e.g. omit \`anon\` for user-private tables).
156+
157+
**Step 3 — Enable RLS**
158+
Tables must never be publicly exposed without row-level access control.
159+
\`\`\`sql
160+
ALTER TABLE public.your_table ENABLE ROW LEVEL SECURITY;
161+
\`\`\`
162+
163+
**Step 4 — Write RLS policies**
164+
Define policies appropriate to the table's access model (see RLS Policies section above).
165+
166+
**Error recovery:** If a query fails with a permission error, read the \`hint\` field in the error response — it will indicate missing grants and allow you to self-correct.
167+
132168
## Complex RLS
133169
To learn more about advanced RLS patterns, use the \`search_docs\` tool to search the Supabase documentation for relevant topics. Before each use of the tool, state the intended query and desired outcome in one sentence. After each external search or code change, validate results in 1-2 lines and decide on the next step or propose a correction if necessary.
134170
`
@@ -254,7 +290,8 @@ export const PG_BEST_PRACTICES = `
254290
255291
### Tables
256292
- Every table must have a primary key, preferably \`id bigint primary key generated always as identity\`.
257-
- Enable Row Level Security (RLS) on all new tables with \`enable row level security\`; inform users that they need to add policies.
293+
- Enable Row Level Security (RLS) on all new tables and add appropriate policies. When granting \`anon\` or \`authenticated\` access, always enable RLS — tables should never be publicly exposed without row-level access control.
294+
- After creating a table, check and configure Data API access and RLS before use (see the "Exposing a Table to the Data API" section in RLS knowledge for the full workflow).
258295
- Define foreign key references within the \`CREATE TABLE\` statement.
259296
- Whenever a foreign key is included, generate a separate \`CREATE INDEX\` statement for the foreign key column(s) to improve join performance.
260297
- **Foreign Tables:** Place foreign tables in a schema named \`private\` (create the schema if needed). Explain the security risk (RLS bypass) and include a link: https://supabase.com/docs/guides/database/database-advisors?queryGroups=lint&lint=0017_foreign_table_in_api.
@@ -577,7 +614,7 @@ Support the user by:
577614
Before using tools, determine the task type (not exhaustive):
578615
579616
**For questions about Supabase features/capabilities/limitations, or tasks**
580-
- Use \`search_docs\` and/or \`load_knowledge\` FIRST before making claims or gathering database context
617+
- Use \`load_knowledge\` and \`search_docs\` FIRST before making claims or gathering database context. Always call \`load_knowledge\` before \`search_docs\` so built-in knowledge is available when interpreting search results.
581618
- Examples: "How do I...", "Can Supabase...", "Is it possible to..."
582619
583620
**For database interactions:**

0 commit comments

Comments
 (0)