Oak Search
Oak Search is a thin orchestration layer over Elasticsearch that adds per-tenant index isolation, query rewriting for access control, and a structured query DSL consumable from TypeScript.
The Problem It Solves
Multi-tenant search has a nasty default: if tenants share an index, a misconfigured query can return documents from the wrong tenant. Oak Search enforces isolation at the query layer — every search request is rewritten to include a tenant filter before hitting Elasticsearch.
Query Rewriting
const search = async (tenantId: string, query: SearchQuery) => {
const safe: ElasticQuery = {
bool: {
must: [toElasticQuery(query)],
filter: [{ term: { tenant_id: tenantId } }], // injected, not user-controlled
},
}
return elastic.search({ index: 'documents', body: { query: safe } })
}
The tenant_id filter is always injected server-side. The caller has no way to omit or override it.
Performance
With a 10M document corpus split across 8 tenants, median search latency is 42ms. The Elasticsearch cluster uses ILM policies to automatically move older indices to frozen tier storage, keeping hot-tier costs stable as the dataset grows.
Status
In production for two tenants. Expanding to a third tenant in the next sprint.