Skip to content

Commit

Permalink
feat: supabase vault (#1605)
Browse files Browse the repository at this point in the history
# Description

#1551

## Checklist before requesting a review

Please delete options that are not relevant.

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my code
- [ ] I have commented hard-to-understand areas
- [ ] I have ideally added tests that prove my fix is effective or that
my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged

## Screenshots (if appropriate):
  • Loading branch information
gozineb authored Nov 7, 2023
1 parent dd2bc1f commit ed5de8b
Show file tree
Hide file tree
Showing 37 changed files with 216 additions and 6 deletions.
3 changes: 3 additions & 0 deletions backend/repository/external_api_secret/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .create_secret import create_secret
from .delete_secret import delete_secret
from .read_secret import read_secret
21 changes: 21 additions & 0 deletions backend/repository/external_api_secret/create_secret.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from uuid import UUID

from models import get_supabase_client
from utils import build_secret_unique_name


def create_secret(
user_id: UUID, brain_id: UUID, secret_name: str, secret_value
) -> UUID | None:
supabase_client = get_supabase_client()
response = supabase_client.rpc(
"insert_secret",
{
"name": build_secret_unique_name(
user_id=user_id, brain_id=brain_id, secret_name=secret_name
),
"secret": secret_value,
},
).execute()

return response.data
18 changes: 18 additions & 0 deletions backend/repository/external_api_secret/delete_secret.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from uuid import UUID

from models import get_supabase_client
from utils import build_secret_unique_name


def delete_secret(user_id: UUID, brain_id: UUID, secret_name: str) -> bool:
supabase_client = get_supabase_client()
response = supabase_client.rpc(
"delete_secret",
{
"name": build_secret_unique_name(
user_id=user_id, brain_id=brain_id, secret_name=secret_name
),
},
).execute()

return response.data
20 changes: 20 additions & 0 deletions backend/repository/external_api_secret/read_secret.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from uuid import UUID

from models import get_supabase_client
from utils import build_secret_unique_name


def read_secret(
user_id: UUID, brain_id: UUID, secret_name: str, secret_value
) -> UUID | None:
supabase_client = get_supabase_client()
response = supabase_client.rpc(
"read_secret",
{
"secret_name": build_secret_unique_name(
user_id=user_id, brain_id=brain_id, secret_name=secret_name
),
},
).execute()

return response.data
5 changes: 5 additions & 0 deletions backend/repository/external_api_secret/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from uuid import UUID


def build_secret_unique_name(user_id: UUID, brain_id: UUID, secret_name: str):
return f"{user_id}-{brain_id}-{secret_name}"
53 changes: 53 additions & 0 deletions scripts/20231107104700_setup_vault.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
CREATE OR REPLACE FUNCTION insert_secret(name text, secret text)
returns uuid
language plpgsql
security definer
set search_path = public
as $$
begin
return vault.create_secret(secret, name);
end;
$$;


create or replace function read_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
secret text;
begin
select decrypted_secret from vault.decrypted_secrets where name =
secret_name into secret;
return secret;
end;
$$;

create or replace function delete_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
deleted_rows int;
begin
delete from vault.decrypted_secrets where name = secret_name;
get diagnostics deleted_rows = row_count;
if deleted_rows = 0 then
return false;
else
return true;
end if;
end;
$$;

-- Insert a migration record if it doesn't exist
INSERT INTO migrations (name)
SELECT '20231107104700_setup_vault'
WHERE NOT EXISTS (
SELECT 1 FROM migrations WHERE name = '20231107104700_setup_vault'
);

-- Commit the changes
COMMIT;
File renamed without changes.
File renamed without changes.
File renamed without changes.
50 changes: 48 additions & 2 deletions scripts/pg_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,59 @@ CREATE TABLE IF NOT EXISTS brain_subscription_invitations (
FOREIGN KEY (brain_id) REFERENCES brains (brain_id)
);

-- Create functions for secrets in vault
CREATE OR REPLACE FUNCTION insert_secret(name text, secret text)
returns uuid
language plpgsql
security definer
set search_path = public
as $$
begin
return vault.create_secret(secret, name);
end;
$$;


create or replace function read_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
secret text;
begin
select decrypted_secret from vault.decrypted_secrets where name =
secret_name into secret;
return secret;
end;
$$;

create or replace function delete_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
deleted_rows int;
begin
delete from vault.decrypted_secrets where name = secret_name;
get diagnostics deleted_rows = row_count;
if deleted_rows = 0 then
return false;
else
return true;
end if;
end;
$$;


CREATE TABLE IF NOT EXISTS migrations (
name VARCHAR(255) PRIMARY KEY,
executed_at TIMESTAMPTZ DEFAULT current_timestamp
);

INSERT INTO migrations (name)
SELECT '202307111517031_change_vectors_id_type'
SELECT '20231107104700_setup_vault'
WHERE NOT EXISTS (
SELECT 1 FROM migrations WHERE name = '202307111517031_change_vectors_id_type'
SELECT 1 FROM migrations WHERE name = '20231107104700_setup_vault'
);
52 changes: 48 additions & 4 deletions scripts/tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,54 @@ CREATE POLICY "Access Quivr Storage 1jccrwz_2" ON storage.objects FOR UPDATE TO

CREATE POLICY "Access Quivr Storage 1jccrwz_3" ON storage.objects FOR DELETE TO anon USING (bucket_id = 'quivr');

-- Create functions for secrets in vault
CREATE OR REPLACE FUNCTION insert_secret(name text, secret text)
returns uuid
language plpgsql
security definer
set search_path = public
as $$
begin
return vault.create_secret(secret, name);
end;
$$;


create or replace function read_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
secret text;
begin
select decrypted_secret from vault.decrypted_secrets where name =
secret_name into secret;
return secret;
end;
$$;

create or replace function delete_secret(secret_name text)
returns text
language plpgsql
security definer set search_path = public
as $$
declare
deleted_rows int;
begin
delete from vault.decrypted_secrets where name = secret_name;
get diagnostics deleted_rows = row_count;
if deleted_rows = 0 then
return false;
else
return true;
end if;
end;
$$;


INSERT INTO migrations (name)
SELECT '20231106110000_add_field_brain_type_to_brain_table'
SELECT '20231107104700_setup_vault'
WHERE NOT EXISTS (
SELECT 1 FROM migrations WHERE name = '20231106110000_add_field_brain_type_to_brain_table'
SELECT 1 FROM migrations WHERE name = '20231107104700_setup_vault'
);


0 comments on commit ed5de8b

Please sign in to comment.