- Per-user Fernet encryption for fact/chunk_text/summary fields - Postgres RLS with memory_app restricted role - SSL for memory-db connections - Data migration script (migrate_encrypt.py) - DB migration (migrate_rls.sql) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
41 lines
1.5 KiB
SQL
41 lines
1.5 KiB
SQL
-- MAT-107: Row-Level Security for memory tables
|
|
-- Run as superuser (memory) which owns the tables
|
|
|
|
-- Create restricted role for memory-service
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'memory_app') THEN
|
|
CREATE ROLE memory_app LOGIN PASSWORD 'OhugBZP4g4d7rk3OszOq1Xe3yo7hQwEn';
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
-- Grant permissions to memory_app
|
|
GRANT CONNECT ON DATABASE memories TO memory_app;
|
|
GRANT USAGE ON SCHEMA public TO memory_app;
|
|
GRANT SELECT, INSERT, DELETE ON memories, conversation_chunks TO memory_app;
|
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO memory_app;
|
|
|
|
-- Ensure tables are owned by memory (superuser) so RLS doesn't apply to owner
|
|
ALTER TABLE memories OWNER TO memory;
|
|
ALTER TABLE conversation_chunks OWNER TO memory;
|
|
|
|
-- Enable RLS
|
|
ALTER TABLE memories ENABLE ROW LEVEL SECURITY;
|
|
ALTER TABLE conversation_chunks ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Drop existing policies if re-running
|
|
DROP POLICY IF EXISTS user_isolation_memories ON memories;
|
|
DROP POLICY IF EXISTS user_isolation_chunks ON conversation_chunks;
|
|
|
|
-- RLS policies: rows visible only when session var matches user_id
|
|
-- current_setting with missing_ok=true returns empty string if not set
|
|
CREATE POLICY user_isolation_memories ON memories
|
|
USING (user_id = current_setting('app.current_user_id', true));
|
|
|
|
CREATE POLICY user_isolation_chunks ON conversation_chunks
|
|
USING (user_id = current_setting('app.current_user_id', true));
|
|
|
|
-- Verify
|
|
SELECT tablename, rowsecurity FROM pg_tables WHERE tablename IN ('memories', 'conversation_chunks');
|