Permissions inside the query
Access checks are part of the database query itself, not a filter bolted on afterwards.
Search everything you're allowed to see, and nothing you're not.
One search contract covers organizations, projects, and notes together or separately. Permission checks run inside the query itself, so results can never include another company's data. Built-in limits keep any search from hammering your database.
Product example
This is the same visual component used by the authenticated app, rendered with deterministic sample data.
Search results include only accessible organizations, projects, and documents.
Inert sample data · no network access
Preview ready
Highlights
Access checks are part of the database query itself, not a filter bolted on afterwards.
Queries cap at 100 characters and 20 globally ranked results, so search can't overload your database.
Search one registered resource type, a named group, or any composition of both; the registry documents what's searchable, by whom, and with what limits.
Without a shared foundation, every team rebuilds these edge cases — differently.
Search that fetches everything and filters afterwards will eventually skip the filter. One missed code path, and another company's rows land in your customer's results.
Without caps, one long query or one huge result set becomes a self-inflicted outage. Your own search box takes your database down.
When nobody wrote down what's searchable under which permission, every new feature reinvents search and re-audits access from scratch.
The mechanism end to end, as implemented in the repository.
Input gets checked first
The query must be 1 to 100 characters, resource types and groups must be registered, results are capped at 20, and wildcard characters are escaped before database work begins.
The server picks the scope
Your active organization and project come from the login session. The browser never gets a say in whose data is searched.
Permissions join the query
Membership checks are joined right into the search query, so rows are narrowed down before matching even runs.
Only selected lanes run
Groups and explicit types resolve to one canonical set. Only selected, authorized query lanes run before results receive one global relevance order.
Engineering guarantees
Search results help people find things; they don't grant access. Every feature checks permissions again when someone opens or edits what they found.
The boundary above is code, not a claim. These files carry the contract:
src/db/postgres-search.tssrc/registries/search-indexes.tssrc/features/search/targets.tssrc/features/search/server.tsThese capabilities share contracts and boundaries with this one.
The docs describe the same contracts this page demonstrates.