← All work

AI · Data · Security · 2026

Permission-aware AI search across many companies' data

A multi-tenant AI search assistant (RAG) on PostgreSQL and pgvector for a SaaS product: staff get answers only from records they may see.

  1. 01QuestionAsked in the staff member's own words.
  2. 02PlanThe model picks search, SQL or both, guided by business terms.
  3. 03Permission filterGateCompany schema, groups and shared people decide what can be read.
  4. 04RerankHybrid search, then in-process reranking puts the best record first.
  5. 05AnswerCited sources, with Right/Wrong marks for reviewing misses.
Answers come only from records the person may see, and the database enforces it.
questions with the right record first after reranking, up from 28
34/40
question types answered with SQL planning, up from 5
12/13
per question with a term picker, down from about 38 s
~12 s

Context

Data must not cross between client companies, and an HR record must not reach a sales employee. Self-serve ruled out asking clients to restructure data.

My role

Solo: architecture, code, evaluation and the Docker Compose setup.

What I built

  • Architecture: pgvector as main store and Pinecone behind one interface, so features need no store branches.
  • Frontend: Chat screen with cited sources and Right/Wrong marks plus comments for reviewing misses.
  • Backend: FastAPI service; PostgreSQL and Dropbox connectors tag chunks with company, groups and shared people.
  • Data & AI: Hybrid search, in-process reranking, and model-planned search, SQL or both, guided by business terms.
  • Security: Model-written SQL runs read-only behind row-level security and a parser check; uploads parse in time-limited child processes.
  • Infrastructure & DevOps: Docker Compose; one command builds each company's schema, indexes and logins from config.
  • Testing: 486 automated tests, including isolation on both stores; five before/after evaluations decided what stayed.

Hard problems and decisions

  • Shared index or schema per company. I chose schemas, so the database, not application code, blocks cross-company reads. Cost: more objects.
  • Model-written SQL. I chose a synced copy over live client databases: no load on clients, but data only as fresh as the last sync.
  • Too many business terms. 300 terms cost about 38 s per question; a picker cut it to about 12 s, with the right terms for 41 of 41 test questions.

Outcome

On a synthetic evaluation set: reranking put the right record first for 34 of 40 questions (from 28); SQL planning answered 12 of 13 question types (from 5); terms lifted a wording test from 44 to 51 of 53.

Stack

Python, FastAPI, PostgreSQL, pgvector, Pinecone, Ollama, Dropbox API

Areas

Architecture, Frontend, Backend, Data, AI, Security, Infrastructure & DevOps, Testing

Period

Oct 2026 – present

Next caseAI content pipeline