mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 04:15:04 +03:00
<img width="783" height="414" alt="Screenshot 2026-04-20 at 3 02 37 PM" src="https://github.com/user-attachments/assets/a353c35a-3de5-4bfa-ab31-829c79c43165" /> Adds a "Default privileges for new entities" checkbox under "Enable Data API" in both the main create flow and the Vercel deploy-button flow. Default checked (current behaviour). When unchecked, runs `buildDefaultPrivilegesSql('revoke')` after the base init script so new entities in `public` aren't auto-granted to `anon` / `authenticated` / `service_role`. This PR decouples the two surfaces: - **`tableEditorApiAccessToggle`** — unchanged; still gates only the integrations → Data API settings UI. - **`dataApiRevokeOnCreateDefault`** (new) — controls only the default state of the new checkbox at project creation. `true` → checkbox unchecked by default (revoke runs); `false`/absent → checkbox checked by default (no behaviour change). The new flag is already live in PostHog at **0% rollout, off for everyone**, so shipping this PR changes nothing until the flag is explicitly flipped. ## Added - `apps/studio/hooks/misc/useDataApiRevokeOnCreateDefault.ts` — reads the new PostHog flag. Returns `false` in `IS_TEST_ENV` so existing E2E flows don't silently change default behaviour. - Checkbox UI in `SecurityOptions.tsx` (main flow) and `pages/integrations/vercel/[slug]/deploy-button/new-project.tsx` (Vercel flow), with copy matching the integrations → Data API settings page. - Tooltip + dimmed state for the main-flow checkbox when "Enable Data API" is unchecked (can't configure default privileges if Data API is off). - Telemetry: `dataApiDefaultPrivilegesGranted` (raw checkbox value) and `dataApiRevokeOnCreateDefaultEnabled` (raw flag, conditionally included using the existing raw-flag pattern so undefined flag state → omitted property, not `false`). - Vitest unit tests for the new hook. ## Changed - `pages/new/[slug].tsx`: removed the `false &&` rollback guard. Revoke SQL now runs only when `dataApi && !dataApiDefaultPrivileges`. Dropped the now-unused `useDataApiGrantTogglesEnabled` import. - `pages/integrations/vercel/[slug]/deploy-button/new-project.tsx`: this flow was **never rolled back** — it still ran revoke whenever `tableEditorApiAccessToggle` was on for a user. Now correctly gated on the new flag + checkbox state. - `packages/common/telemetry-constants.ts`: added the two new properties and corrected the `tableEditorApiAccessToggleEnabled` docstring (it no longer claims to control project-creation revoke behaviour). ## Kill switch Flipping `dataApiRevokeOnCreateDefault` to off in PostHog fully disables the revoke SQL for new projects without needing a redeploy — the checkbox just defaults to checked again. ## Follow-ups (not blockers) - joshenlim's review comments on PR 43704: (1) Auth Policies table row incorrectly showing "exposed via Data API" based on schema-level check instead of table-level at `apps/studio/components/interfaces/Auth/Policies/PolicyTableRow/index.tsx:64`; (2) Data API integrations page showing zero exposed tables even after exposing one. Both unrelated to this PR but will be more visible once the checkbox lands. - Once this flag fully rolls out, the old `tableEditorApiAccessToggle` docstring/comments elsewhere should stop claiming it controls project creation. ## To test - **Flag off (default state, simulates post-merge):** create a project with and without "Enable Data API" checked. The new "Default privileges for new entities" checkbox should default to **checked**. Submitting should produce an identical result to today — new tables in `public` are reachable via the Data API. - **Flag on (simulate rollout):** override the flag locally. The checkbox should default to **unchecked**. Creating a project with it unchecked should run the revoke SQL; create a new table in `public` afterwards and confirm it's not reachable via the Data API until grants are added. - **Enable Data API off:** the new checkbox should render disabled + dimmed with a tooltip reading "Enable the Data API to configure default privileges." The revoke SQL should not run in this case regardless of checkbox state. - **Vercel flow:** repeat at `/integrations/vercel/<slug>/deploy-button/new-project` — verify both checkbox states. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added an "Automatically expose new tables and functions" checkbox to project creation and Vercel deploy flow; enabled only when Data API is available (disabled with tooltip otherwise) and affects initial project provisioning. * **Telemetry** * Tracks exposure of the default-privileges control and includes checkbox state and feature-flag status on project-creation submissions. * **Tests** * Added tests for flag behavior, exposure tracking, deduplication, and submission telemetry. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com> Co-authored-by: Sean Oliver <882952+seanoliver@users.noreply.github.com>
157 lines
5.9 KiB
TypeScript
157 lines
5.9 KiB
TypeScript
import Link from 'next/link'
|
|
import { UseFormReturn } from 'react-hook-form'
|
|
import {
|
|
Checkbox_Shadcn_,
|
|
cn,
|
|
FormControl_Shadcn_,
|
|
FormDescription_Shadcn_,
|
|
FormField_Shadcn_,
|
|
FormItem_Shadcn_,
|
|
FormLabel_Shadcn_,
|
|
Tooltip,
|
|
TooltipContent,
|
|
TooltipTrigger,
|
|
useWatch_Shadcn_,
|
|
} from 'ui'
|
|
import { Admonition } from 'ui-patterns'
|
|
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
|
|
|
|
import { CreateProjectForm } from './ProjectCreation.schema'
|
|
import Panel from '@/components/ui/Panel'
|
|
import { useTrackDefaultPrivilegesExposure } from '@/hooks/misc/useDataApiRevokeOnCreateDefault'
|
|
|
|
interface SecurityOptionsProps {
|
|
form: UseFormReturn<CreateProjectForm>
|
|
layout?: 'vertical' | 'horizontal'
|
|
}
|
|
|
|
export const SecurityOptions = ({ form, layout = 'horizontal' }: SecurityOptionsProps) => {
|
|
const dataApi = useWatch_Shadcn_({ control: form.control, name: 'dataApi' })
|
|
|
|
useTrackDefaultPrivilegesExposure({ surface: 'main', dataApiEnabled: dataApi ?? true })
|
|
|
|
return (
|
|
<Panel.Content className="pb-8">
|
|
<FormItemLayout layout={layout} label="Security" isReactForm={false}>
|
|
<div className="flex flex-col gap-4">
|
|
<FormField_Shadcn_
|
|
name="dataApi"
|
|
control={form.control}
|
|
render={({ field }) => (
|
|
<FormItem_Shadcn_ className="flex items-start gap-3">
|
|
<FormControl_Shadcn_>
|
|
<Checkbox_Shadcn_
|
|
checked={field.value}
|
|
disabled={field.disabled}
|
|
onCheckedChange={(value) => field.onChange(value === true)}
|
|
/>
|
|
</FormControl_Shadcn_>
|
|
<div className="space-y-1">
|
|
<FormLabel_Shadcn_ className="text-sm text-foreground">
|
|
Enable Data API
|
|
</FormLabel_Shadcn_>
|
|
<FormDescription_Shadcn_ className="text-foreground-lighter">
|
|
Autogenerate a RESTful API for your public schema. Recommended if using a client
|
|
library like{' '}
|
|
<Link
|
|
href="https://supabase.com/docs/reference/javascript/introduction"
|
|
target="_blank"
|
|
className="text-link"
|
|
>
|
|
supabase-js
|
|
</Link>
|
|
.
|
|
</FormDescription_Shadcn_>
|
|
</div>
|
|
</FormItem_Shadcn_>
|
|
)}
|
|
/>
|
|
|
|
<FormField_Shadcn_
|
|
name="dataApiDefaultPrivileges"
|
|
control={form.control}
|
|
render={({ field }) => (
|
|
<FormItem_Shadcn_
|
|
className={cn(
|
|
'flex items-start gap-3',
|
|
!dataApi && 'opacity-50 cursor-not-allowed'
|
|
)}
|
|
>
|
|
<FormControl_Shadcn_>
|
|
{dataApi ? (
|
|
<Checkbox_Shadcn_
|
|
checked={field.value}
|
|
disabled={field.disabled}
|
|
onCheckedChange={(value) => field.onChange(value === true)}
|
|
/>
|
|
) : (
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>
|
|
<span className="cursor-not-allowed">
|
|
<Checkbox_Shadcn_ checked={field.value} disabled />
|
|
</span>
|
|
</TooltipTrigger>
|
|
<TooltipContent side="top">
|
|
Enable the Data API to configure default privileges.
|
|
</TooltipContent>
|
|
</Tooltip>
|
|
)}
|
|
</FormControl_Shadcn_>
|
|
<div className="space-y-1">
|
|
<FormLabel_Shadcn_
|
|
className={cn('text-sm text-foreground', !dataApi && 'text-foreground-muted')}
|
|
>
|
|
Automatically expose new tables and functions
|
|
</FormLabel_Shadcn_>
|
|
<FormDescription_Shadcn_ className="text-foreground-lighter">
|
|
Grants privileges to Data API roles by default, exposing new tables and
|
|
functions.
|
|
<br />
|
|
<strong className="font-medium text-foreground-light">
|
|
We recommend disabling this to control access manually.
|
|
</strong>
|
|
</FormDescription_Shadcn_>
|
|
</div>
|
|
</FormItem_Shadcn_>
|
|
)}
|
|
/>
|
|
|
|
<FormField_Shadcn_
|
|
name="enableRlsEventTrigger"
|
|
control={form.control}
|
|
render={({ field }) => (
|
|
<FormItem_Shadcn_ className="flex items-start gap-3">
|
|
<FormControl_Shadcn_>
|
|
<Checkbox_Shadcn_
|
|
checked={field.value}
|
|
disabled={field.disabled}
|
|
onCheckedChange={(value) => field.onChange(value === true)}
|
|
/>
|
|
</FormControl_Shadcn_>
|
|
<div className="space-y-1">
|
|
<FormLabel_Shadcn_ className="text-sm text-foreground">
|
|
Enable automatic RLS
|
|
</FormLabel_Shadcn_>
|
|
<FormDescription_Shadcn_ className="text-foreground-lighter">
|
|
Create an event trigger that automatically enables Row Level Security on all new
|
|
tables in the public schema.
|
|
</FormDescription_Shadcn_>
|
|
</div>
|
|
</FormItem_Shadcn_>
|
|
)}
|
|
/>
|
|
|
|
{!dataApi && (
|
|
<Admonition
|
|
type="warning"
|
|
title="Client libraries need Data API to query your database"
|
|
>
|
|
Disabling it means supabase-js and similar libraries can't query or mutate data.
|
|
</Admonition>
|
|
)}
|
|
</div>
|
|
</FormItemLayout>
|
|
</Panel.Content>
|
|
)
|
|
}
|