PolicyEditorModal.constants.ts329 lines · main
1import { safeSql } from '@supabase/pg-meta/src/pg-format'
2
3import { PolicyTemplate } from '../PolicyTemplates/PolicyTemplates.constants'
4
5/**
6 * ----------------------------------------------------------------
7 * PostgreSQL policy templates for the auth policies page
8 * ----------------------------------------------------------------
9 * id: Unique identifier for the monaco editor to dynamically refresh
10 * templateName: As a display for a more descriptive title for the policy
11 * description: Additional details about the template and how to make it yours
12 * statement: SQL statement template for the policy
13 *
14 * name: Actual policy name that will be used in the editor
15 * definition: Actual policy using expression that will be used in the editor
16 * check: Actual policy with check expression that will be used in the editor
17 * command: Operation to create policy for
18 */
19
20export const getGeneralPolicyTemplates = (schema: string, table: string): PolicyTemplate[] => [
21 {
22 id: 'policy-1',
23 preview: false,
24 templateName: 'Enable read access to everyone',
25 description:
26 'This policy gives read access to your table for all users via the SELECT operation.',
27 statement: `
28create policy "Enable read access for all users"
29on "${schema}"."${table}"
30for select using (true);`.trim(),
31 name: 'Enable read access for all users',
32 definition: safeSql`true`,
33 check: safeSql``,
34 command: 'SELECT',
35 roles: [],
36 },
37 {
38 id: 'policy-2',
39 preview: false,
40 templateName: 'Enable insert access for authenticated users only',
41 description: 'This policy gives insert access to your table for all authenticated users only.',
42 statement: `
43create policy "Enable insert for authenticated users only"
44on "${schema}"."${table}"
45for insert to authenticated
46with check (true);`.trim(),
47 name: 'Enable insert for authenticated users only',
48 definition: safeSql``,
49 check: safeSql`true`,
50 command: 'INSERT',
51 roles: ['authenticated'],
52 },
53 {
54 id: 'policy-3',
55 preview: false,
56 templateName: 'Enable delete access for users based on their user ID *',
57 description:
58 'This policy assumes that your table has a column "user_id", and allows users to delete rows which the "user_id" column matches their ID',
59 statement: `
60create policy "Enable delete for users based on user_id"
61on "${schema}"."${table}"
62for delete using (
63 (select auth.uid()) = user_id
64);`.trim(),
65 name: 'Enable delete for users based on user_id',
66 definition: safeSql`(select auth.uid()) = user_id`,
67 check: safeSql``,
68 command: 'DELETE',
69 roles: [],
70 },
71 {
72 id: 'policy-4',
73 preview: false,
74 templateName: 'Enable insert access for users based on their user ID *',
75 description:
76 'This policy assumes that your table has a column "user_id", and allows users to insert rows which the "user_id" column matches their ID',
77 statement: `
78create policy "Enable insert for users based on user_id"
79on "${schema}"."${table}"
80for insert with check (
81 (select auth.uid()) = user_id
82);`.trim(),
83 name: 'Enable insert for users based on user_id',
84 definition: safeSql``,
85 check: safeSql`(select auth.uid()) = user_id`,
86 command: 'INSERT',
87 roles: [],
88 },
89 {
90 id: 'policy-5',
91 preview: true,
92 name: 'Policy with table joins',
93 templateName: 'Policy with table joins',
94 description: `
95Query across tables to build more advanced RLS rules
96
97Assuming 2 tables called \`teams\` and \`members\`, you can query both tables in the policy to control access to the members table.`,
98 statement: `
99create policy "Members can update team details if they belong to the team"
100on teams for update using (
101 (select auth.uid()) in (
102 select user_id from members where team_id = id
103 )
104);
105`.trim(),
106 definition: safeSql`(select auth.uid()) in (select user_id from members where team_id = id)`,
107 check: safeSql``,
108 command: 'UPDATE',
109 roles: [],
110 },
111 {
112 id: 'policy-6',
113 preview: true,
114 templateName: 'Policy with security definer functions',
115 description: `
116Useful in a many-to-many relationship where you want to restrict access to the linking table.
117
118Assuming 2 tables called \`teams\` and \`members\`, you can use a security definer function in combination with a policy to control access to the members table.`.trim(),
119 statement: `
120create or replace function get_teams_for_user(user_id uuid)
121returns setof bigint as $$
122 select team_id from members where user_id = $1
123$$ stable language sql security definer;
124
125create policy "Team members can update team members if they belong to the team"
126on members
127for all using (
128 team_id in (select get_teams_for_user(auth.uid()))
129);
130`.trim(),
131 name: 'Policy with security definer functions',
132 definition: safeSql`team_id in (select get_teams_for_user(auth.uid()))`,
133 check: safeSql``,
134 command: 'ALL',
135 roles: [],
136 },
137 {
138 id: 'policy-7',
139 preview: true,
140 name: 'Policy to implement Time To Live (TTL)',
141 templateName: 'Policy to implement Time To Live (TTL)',
142 description: `
143Implement a TTL-like feature that you see in Instagram stories or Snapchat where messages expire after a day.
144
145Rows under the table are available only if they have been created within the last 24 hours.`,
146 statement: `
147create policy "Stories are live for a day"
148on "${schema}"."${table}"
149for select using (
150 created_at > (current_timestamp - interval '1 day')
151);
152`.trim(),
153 definition: safeSql`created_at > (current_timestamp - interval '1 day')`,
154 check: safeSql``,
155 command: 'SELECT',
156 roles: [],
157 },
158 {
159 id: 'policy-8',
160 preview: false,
161 templateName: 'Allow users to only view their own data',
162 description: 'Restrict users to reading only their own data.',
163 statement: `
164create policy "Enable users to view their own data only"
165on "${schema}"."${table}"
166for select
167to authenticated
168using (
169 (select auth.uid()) = user_id
170);`.trim(),
171 name: 'Enable users to view their own data only',
172 definition: safeSql`(select auth.uid()) = user_id`,
173 check: safeSql``,
174 command: 'SELECT',
175 roles: ['authenticated'],
176 },
177]
178
179export const getRealtimePolicyTemplates = (): PolicyTemplate[] => {
180 const results = [
181 {
182 id: 'policy-broadcast-1',
183 preview: false,
184 templateName: 'Allow listening for broadcasts for authenticated users only',
185 description: 'This policy allows listening for broadcasts for authenticated users only.',
186 statement: `
187create policy "Allow listening for broadcasts for authenticated users only"
188on realtime.messages for select
189to authenticated
190using ( realtime.messages.extension = 'broadcast' );`.trim(),
191 name: 'Allow listening for broadcasts for authenticated users only',
192 definition: safeSql`realtime.messages.extension = 'broadcast'`,
193 check: safeSql``,
194 command: 'SELECT',
195 roles: ['authenticated'],
196 },
197 {
198 id: 'policy-broadcast-2',
199 preview: false,
200 templateName: 'Allow pushing broadcasts for authenticated users only',
201 description: 'This policy allows pushing broadcasts for authenticated users only.',
202 statement: `
203create policy "Allow pushing broadcasts for authenticated users only"
204ON realtime.messages for insert
205TO authenticated
206with check ( realtime.messages.extension = 'broadcast' );`.trim(),
207 name: 'Allow pushing broadcasts for authenticated users only',
208 definition: safeSql`realtime.messages.extension = 'broadcast'`,
209 check: safeSql`realtime.messages.extension = 'broadcast'`,
210 command: 'INSERT',
211 roles: ['authenticated'],
212 },
213 {
214 id: 'policy-broadcast-3',
215 preview: false,
216 templateName: 'Allow listening for broadcasts from a specific channel',
217 description: 'This policy allows listening for broadcasts from a specific channel.',
218 statement: `
219create policy "Allow listening for broadcasts from a specific channel"
220on realtime.messages for select
221using ( realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name' );`.trim(),
222 name: 'Allow listening for broadcasts from a specific channel',
223 definition: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
224 check: safeSql``,
225 command: 'SELECT',
226 roles: [],
227 },
228 {
229 id: 'policy-broadcast-4',
230 preview: false,
231 templateName: 'Allow pushing broadcasts to specific channel',
232 description: 'This policy allow pushing broadcasts to specific channel.',
233 statement: `
234create policy "Allow pushing broadcasts to specific channel"
235ON realtime.messages for insert
236with check ( realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name' );`.trim(),
237 name: 'Allow pushing broadcasts to specific channel',
238 definition: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
239 check: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
240 command: 'INSERT',
241 roles: [],
242 },
243 {
244 id: 'policy-presences-1',
245 preview: false,
246 templateName: 'Allow listening for presences on all channels for authenticated users only',
247 description:
248 'This policy enables listening for presences on all channels for all authenticated users only.',
249 statement: `
250create policy "Allow listening for presences on all channels for authenticated users only"
251on realtime.messages for select
252to authenticated
253using ( realtime.messages.extension = 'presence' );`.trim(),
254 name: 'Allow listening for presences on all channels for authenticated users only',
255 definition: safeSql`realtime.messages.extension = 'presence'`,
256 check: safeSql``,
257 command: 'SELECT',
258 roles: ['authenticated'],
259 },
260 {
261 id: 'policy-presences-2',
262 preview: false,
263 templateName: 'Allow broadcasting presences on all channels for authenticated users only',
264 description:
265 'This policy enables broadcasting presences on all channels for all authenticated users only.',
266 statement: `
267create policy "Allow broadcasting presences on all channels for authenticated users only"
268ON realtime.messages for insert
269TO authenticated
270with check ( realtime.messages.extension = 'presence' );
271 ;`.trim(),
272 name: 'Allow broadcasting presences on all channels for authenticated users only',
273 definition: safeSql`realtime.messages.extension = 'presence'`,
274 check: safeSql`realtime.messages.extension = 'presence'`,
275 command: 'INSERT',
276 roles: ['authenticated'],
277 },
278 {
279 id: 'policy-presences-3',
280 preview: false,
281 templateName: 'Allow listening for presences from a specific channel',
282 description: 'This policy enables listening for presences from a specific channel.',
283 statement: `
284create policy "Allow listening for presences from a specific channel"
285on realtime.messages for select
286using ( realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name' );`.trim(),
287 name: 'Allow listening for presences from a specific channel',
288 definition: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
289 check: safeSql``,
290 command: 'SELECT',
291 roles: [],
292 },
293 {
294 id: 'policy-presences-4',
295 preview: false,
296 templateName: 'Publish presence to a specific channel',
297 description: 'This policy allows publishing presence to a specific channel.',
298 statement: `
299create policy "Publish presence to a specific channel"
300ON realtime.messages for insert
301with check ( realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name' );
302 ;`.trim(),
303 name: 'Publish presence to a specific channel',
304 definition: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
305 check: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
306 command: 'INSERT',
307 roles: [],
308 },
309 ] as PolicyTemplate[]
310 return results
311}
312
313export const getQueuePolicyTemplates = (): PolicyTemplate[] => {
314 return [
315 {
316 id: 'policy-queues-1',
317 preview: false,
318 templateName: 'Allow access to queue',
319 statement: ``.trim(),
320 name: 'Allow anon and authenticated to access messages from queue',
321 description:
322 'Base policy to ensure that anon and authenticated can only access appropriate rows. USING and CHECK statements will need to be adjusted accordingly',
323 definition: safeSql`true`,
324 check: safeSql`true`,
325 command: 'ALL',
326 roles: ['anon', 'authenticated'],
327 },
328 ]
329}