fix(evidence): enforce active vector generations
This commit is contained in:
@@ -28,7 +28,9 @@ $$;
|
||||
create or replace function public.search_similar(
|
||||
table_name text,
|
||||
query_embedding vector,
|
||||
limit_count integer
|
||||
limit_count integer,
|
||||
kinds text[] default null,
|
||||
metadata_filter jsonb default null
|
||||
)
|
||||
returns table(id bigint, similarity real, metadata jsonb)
|
||||
language plpgsql
|
||||
@@ -37,15 +39,31 @@ set search_path = public, vectors, extensions
|
||||
as $$
|
||||
begin
|
||||
perform public._assert_vector_read_table(table_name);
|
||||
if metadata_filter is not null and (
|
||||
table_name <> 'evidence'
|
||||
or not (metadata_filter ? 'vector_generation')
|
||||
or not (metadata_filter ? 'document_ids')
|
||||
or jsonb_object_length(metadata_filter) <> 2
|
||||
or jsonb_typeof(metadata_filter->'document_ids') <> 'array'
|
||||
) then
|
||||
raise exception 'invalid Evidence metadata filter';
|
||||
end if;
|
||||
return query execute format(
|
||||
'select t.id,
|
||||
(1 - (t.embedding <=> $1))::real as similarity,
|
||||
t.metadata
|
||||
from vectors.%I t
|
||||
where ($3 is null or t.kind = any ($3))
|
||||
and ($4 is null or (
|
||||
t.metadata->>''vector_generation'' = $4->>''vector_generation''
|
||||
and t.metadata->>''document_id'' in (
|
||||
select jsonb_array_elements_text($4->''document_ids'')
|
||||
)
|
||||
))
|
||||
order by t.embedding <=> $1
|
||||
limit $2',
|
||||
table_name
|
||||
) using query_embedding, limit_count;
|
||||
) using query_embedding, limit_count, kinds, metadata_filter;
|
||||
end;
|
||||
$$;
|
||||
|
||||
@@ -75,7 +93,7 @@ end;
|
||||
$$;
|
||||
|
||||
revoke all on function public._assert_vector_read_table(text) from public;
|
||||
revoke all on function public.search_similar(text, vector, integer) from public;
|
||||
revoke all on function public.search_similar(text, vector, integer, text[], jsonb) from public;
|
||||
revoke all on function public.list_tables() from public;
|
||||
|
||||
-- Revoca dai ruoli client generici, poi abilita solo il reader dedicato
|
||||
@@ -83,15 +101,16 @@ revoke all on function public.list_tables() from public;
|
||||
do $$
|
||||
begin
|
||||
if exists (select 1 from pg_roles where rolname = 'anon') then
|
||||
revoke all on function public.search_similar(text, vector, integer) from anon;
|
||||
revoke all on function public.search_similar(text, vector, integer, text[], jsonb) from anon;
|
||||
revoke all on function public.list_tables() from anon;
|
||||
end if;
|
||||
if exists (select 1 from pg_roles where rolname = 'authenticated') then
|
||||
revoke all on function public.search_similar(text, vector, integer) from authenticated;
|
||||
revoke all on function public.search_similar(text, vector, integer, text[], jsonb) from authenticated;
|
||||
revoke all on function public.list_tables() from authenticated;
|
||||
end if;
|
||||
if exists (select 1 from pg_roles where rolname = 'vector_reader') then
|
||||
grant execute on function public.search_similar(text, vector, integer) to vector_reader;
|
||||
grant execute on function public.search_similar(text, vector, integer, text[], jsonb)
|
||||
to vector_reader;
|
||||
grant execute on function public.list_tables() to vector_reader;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
@@ -101,9 +101,30 @@ begin
|
||||
end;
|
||||
$$;
|
||||
|
||||
create or replace function public.delete_vector_generation(
|
||||
table_name text, kind text, generation text
|
||||
)
|
||||
returns jsonb
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public, vectors, extensions
|
||||
as $$
|
||||
declare affected integer;
|
||||
begin
|
||||
if table_name <> 'evidence' or kind <> 'evidence' or generation !~ '^gen:[0-9a-f]{32}$' then
|
||||
raise exception 'only an exact Evidence generation may be deleted';
|
||||
end if;
|
||||
delete from vectors.evidence e
|
||||
where e.kind = 'evidence' and e.metadata->>'vector_generation' = generation;
|
||||
get diagnostics affected = row_count;
|
||||
return jsonb_build_object('deleted', affected);
|
||||
end;
|
||||
$$;
|
||||
|
||||
revoke all on function public._assert_vector_write_table(text, text[]) from public;
|
||||
revoke all on function public.existing_vector_hashes(text, text[]) from public;
|
||||
revoke all on function public.upsert_vector_records(text, jsonb) from public;
|
||||
revoke all on function public.delete_vector_generation(text, text, text) from public;
|
||||
|
||||
-- Su alcuni progetti Supabase le funzioni in `public` ricevono grant automatici: revoca
|
||||
-- esplicitamente dai ruoli client generici, poi abilita solo il writer dedicato.
|
||||
@@ -112,14 +133,17 @@ begin
|
||||
if exists (select 1 from pg_roles where rolname = 'anon') then
|
||||
revoke all on function public.existing_vector_hashes(text, text[]) from anon;
|
||||
revoke all on function public.upsert_vector_records(text, jsonb) from anon;
|
||||
revoke all on function public.delete_vector_generation(text, text, text) from anon;
|
||||
end if;
|
||||
if exists (select 1 from pg_roles where rolname = 'authenticated') then
|
||||
revoke all on function public.existing_vector_hashes(text, text[]) from authenticated;
|
||||
revoke all on function public.upsert_vector_records(text, jsonb) from authenticated;
|
||||
revoke all on function public.delete_vector_generation(text, text, text) from authenticated;
|
||||
end if;
|
||||
if exists (select 1 from pg_roles where rolname = 'vector_writer') then
|
||||
grant execute on function public.existing_vector_hashes(text, text[]) to vector_writer;
|
||||
grant execute on function public.upsert_vector_records(text, jsonb) to vector_writer;
|
||||
grant execute on function public.delete_vector_generation(text, text, text) to vector_writer;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user