[verified] add taxonomy storage RLS policies
Some checks failed
supabase-ci / validate (push) Has been cancelled
Some checks failed
supabase-ci / validate (push) Has been cancelled
(cherry picked from commit bebd0e6312370620dc1e9df97f7e80076a7654be)
This commit is contained in:
parent
75a0779a3a
commit
e856de79b8
108
volumes/db/cc/77-storage-taxonomy-rls.sql
Normal file
108
volumes/db/cc/77-storage-taxonomy-rls.sql
Normal file
@ -0,0 +1,108 @@
|
||||
-- 77-storage-taxonomy-rls.sql
|
||||
-- RLS for taxonomy storage buckets. cc.examboards intentionally gets no
|
||||
-- direct object-read policy: exam-board PDF bytes are exposed only through
|
||||
-- API-issued, time-limited signed URLs.
|
||||
|
||||
create or replace function public.is_platform_admin()
|
||||
returns boolean
|
||||
language sql
|
||||
stable
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
select exists (
|
||||
select 1
|
||||
from public.admin_profiles ap
|
||||
where ap.id = auth.uid()
|
||||
and coalesce(ap.is_super_admin, false)
|
||||
)
|
||||
$$;
|
||||
|
||||
grant execute on function public.is_platform_admin() to authenticated;
|
||||
|
||||
-- Use the first path segment of cc.institutes objects as the institute id.
|
||||
-- Expected layout: cc.institutes/<institute_uuid>/...
|
||||
create or replace function public.storage_object_first_path_segment_uuid(p_name text)
|
||||
returns uuid
|
||||
language plpgsql
|
||||
immutable
|
||||
as $$
|
||||
declare
|
||||
v_segment text;
|
||||
begin
|
||||
v_segment := split_part(coalesce(p_name, ''), '/', 1);
|
||||
if v_segment = '' then
|
||||
return null;
|
||||
end if;
|
||||
begin
|
||||
return v_segment::uuid;
|
||||
exception when invalid_text_representation then
|
||||
return null;
|
||||
end;
|
||||
end;
|
||||
$$;
|
||||
|
||||
grant execute on function public.storage_object_first_path_segment_uuid(text) to authenticated;
|
||||
|
||||
-- Exam-board catalogue rows are authenticated metadata. PDF bytes remain
|
||||
-- protected separately in cc.examboards storage and require signed URLs.
|
||||
alter table public.eb_specifications enable row level security;
|
||||
alter table public.eb_exams enable row level security;
|
||||
|
||||
drop policy if exists "eb_specifications read by authenticated users" on public.eb_specifications;
|
||||
drop policy if exists "eb_exams read by authenticated users" on public.eb_exams;
|
||||
|
||||
create policy "eb_specifications read by authenticated users"
|
||||
on public.eb_specifications
|
||||
for select
|
||||
to authenticated
|
||||
using (true);
|
||||
|
||||
create policy "eb_exams read by authenticated users"
|
||||
on public.eb_exams
|
||||
for select
|
||||
to authenticated
|
||||
using (true);
|
||||
|
||||
alter table storage.objects enable row level security;
|
||||
|
||||
-- Replace only the policies owned by this migration. The absence of any
|
||||
-- cc.examboards SELECT policy is the deny-by-default posture for raw reads.
|
||||
drop policy if exists "cc.admin objects read by platform admins" on storage.objects;
|
||||
drop policy if exists "cc.institutes objects read by institute members" on storage.objects;
|
||||
drop policy if exists "cc.public objects read by authenticated users" on storage.objects;
|
||||
|
||||
create policy "cc.admin objects read by platform admins"
|
||||
on storage.objects
|
||||
for select
|
||||
to authenticated
|
||||
using (
|
||||
bucket_id = 'cc.admin'
|
||||
and public.is_platform_admin()
|
||||
);
|
||||
|
||||
create policy "cc.institutes objects read by institute members"
|
||||
on storage.objects
|
||||
for select
|
||||
to authenticated
|
||||
using (
|
||||
bucket_id = 'cc.institutes'
|
||||
and public.storage_object_first_path_segment_uuid(name) in (
|
||||
select public.user_institute_ids()
|
||||
)
|
||||
);
|
||||
|
||||
create policy "cc.public objects read by authenticated users"
|
||||
on storage.objects
|
||||
for select
|
||||
to authenticated
|
||||
using (bucket_id = 'cc.public');
|
||||
|
||||
comment on policy "cc.admin objects read by platform admins" on storage.objects
|
||||
is 'cc.admin raw reads are limited to platform admins.';
|
||||
comment on policy "cc.institutes objects read by institute members" on storage.objects
|
||||
is 'cc.institutes raw reads are scoped by leading path segment institute uuid.';
|
||||
comment on policy "cc.public objects read by authenticated users" on storage.objects
|
||||
is 'cc.public raw reads are available to any authenticated user.';
|
||||
comment on table storage.objects
|
||||
is 'Classroom Copilot taxonomy buckets use RLS; cc.examboards raw reads stay denied and are served through API signed URLs.';
|
||||
Loading…
x
Reference in New Issue
Block a user