Search that respects its boundaries
A useful search experience should help someone return to the exact conversation, document or record they need. The difficult part is not simply finding similar text. It is making sure each result still belongs to the person asking, remains current, and opens at the right destination.
This article presents a generalized version of a search solution I designed. Organization names, product identifiers and delivery arrangements have been removed. It describes a proposed architecture and its controls, rather than claiming a deployed system or measured performance.
Start with the experience
Imagine searching for a decision discussed weeks ago. You remember the topic, but not the exact wording or which conversation contained it. Search should support both an exact reference and a natural-language description, then take you to the matching message instead of leaving you at a generic conversation list.
The same capability can serve several interfaces:
- Search inside chat: find a previous exchange without leaving the conversation experience.
- A dedicated search page: explore approved content with agreed filters and destinations.
- An approved agent tool: return typed, permission-checked results for the signed-in user.
- Future workforce tools: a separate extension with its own identity, portfolio scope and field visibility rules.
Sharing a search service does not mean sharing everyone's content. Each interface needs an explicit audience and supported source set. Start with released, eligible conversation content or a selected set of assets. Add channels only when their access rules and destination behavior are understood.
One service, a clear trust boundary
Figure 1. A conceptual AWS service flow. Current source access checks govern content release; retrieval scores do not confer permission.
In the proposed AWS pattern, API Gateway exposes the search operation, a Lambda service coordinates retrieval and release, OpenSearch provides keyword and vector retrieval, and Bedrock supplies query embeddings. Source APIs remain authoritative for current access and content versions.
The backend derives scope from trusted authentication context. A client can request a content type or filter, but cannot grant itself a different audience, account or portfolio simply by supplying a field in the request. A delegated agent operates within the acting user's permitted scope.
The search index is a derived discovery layer. Its access metadata can narrow candidates, but an index entry alone is not evidence that access remains valid.
Make the result contract useful
A shared contract keeps chat, a search page and an agent tool aligned. A result needs more than a snippet: it needs a stable identity, source type, permitted display fields and a supported destination.
The following is an illustrative result shape, not a production API snapshot:
{
"result_id": "example-result",
"source_type": "conversation_message",
"source_version": "example-version",
"title": "A previous discussion",
"snippet": "A permitted excerpt from the matching message.",
"destination": {
"type": "message",
"conversation_id": "example-conversation",
"message_id": "example-message"
}
}
Destination fields should be validated and resolved by the application. They are not permission tokens. When someone opens a result, the destination must check current access again. Deleted or inaccessible content needs an honest unavailable state rather than a stale preview.
Do not return forbidden titles, snippets or facets and rely on the interface to hide them. The service must construct the public response only from permitted fields.
Prepare each source before indexing
Figure 2. Source readiness is part of the architecture. Missing or unsafe metadata takes a quarantine path.
Conversation turns and other assets have different ingestion requirements. Eligible released chat turns may be relatively simple. Documents and records need source-specific adapters and explicit decisions about audience, access, release status, version and destination.
An adapter reads approved source content and attaches the metadata needed to evaluate eligibility. Valid events enter an SQS queue; an indexing worker produces the searchable representation. Invalid or incomplete metadata is quarantined instead of silently accepted.
Version-aware writes and deletes matter because asynchronous events can arrive late or more than once. A delayed update must not restore a document after a newer deletion. An embedding also belongs to a particular content version; a vector for an obsolete version should not be treated as current evidence.
Before adding a source, ask who owns its access decisions, how updates and revocations are emitted, which fields can be displayed, and where a result should open. A connector without those answers is incomplete.
Combine exact terms with meaning
Exact identifiers, keyword matches and semantic similarity solve different problems. A reference number benefits from an exact match. Distinctive terminology benefits from keyword retrieval. A paraphrased question may benefit from embeddings.
The proposed pattern combines these signals rather than replacing lexical search with vectors. BM25 and vector candidates can be fused with reciprocal rank fusion, then optionally reranked within the permitted content boundary.
Use a representative query set with expected results to tune this behavior. Include exact references, paraphrases, ambiguous queries, queries with no relevant result, and queries whose most relevant document is inaccessible. Relevant-but-forbidden content must stay absent.
Candidate limits, fusion settings and reranking are tuning choices. The source design does not establish benchmark results or response-time guarantees.
Check before hydration, then before release
Retrieval can return candidate identifiers and scores. Before fetching display text or sending content into reranking, the service checks current item access, allowed fields and source version. Candidates that cannot be verified should not proceed.
After hydration, check again before constructing the response. This narrows the window in which an access change can invalidate an earlier decision. Destination opening adds another check at the point of use.
These checks do not automatically establish globally atomic revocation. The effective revision, source propagation timing, concurrent changes and release behavior need explicit qualification. If current access cannot be established, fail closed for the affected candidate instead of serving a cached snippet.
Treat revocation as a first-class path
Figure 3. A durable deny record protects the query path while derived index data is being removed.
Index cleanup is asynchronous, so deleting an index document cannot be the only revocation control. The proposed design commits a durable deny revision before acknowledging the source's revocation event. If that write fails, retry without acknowledging success.
A deny record must carry the applicable item, principal or audience, and revision scope. A single user losing access must not accidentally deny the same item to every other permitted user. This key design is an implementation detail to qualify with the source access model.
A query guard reads the deny state using a strongly consistent base-record read. Denied revisions block release. In parallel, version-checked cleanup removes derived text and vectors from the search index.
The durable deny record, current source checks and index purge have distinct responsibilities. Their concurrency behavior must be tested together, including a revocation during an active query and an older update arriving after deletion.
Measure relevance and safe operation
Operational traces should record redacted decisions: request identifiers, decision outcomes, source versions and timing where appropriate. Exclude full query text and retrieved content from routine logs, and restrict audit access.
Agree monitoring thresholds and owners before release. Useful signals include access-check failures, ingestion lag, quarantine growth, stale-version rejection, purge backlog and latency. Establish the relevance and response-time targets before judging tuning results.
Acceptance should cover more than the happy path:
| Scenario | Expected behavior |
|---|---|
| Exact reference or paraphrase | Find the expected permitted result |
| Another audience's content | Exclude it from snippets, results and facets |
| Source access unavailable | Do not release unverified content |
| Revocation during retrieval | Apply qualified current-access and deny checks |
| Late update after deletion | Reject the stale version |
| Result destination opened later | Recheck access and show an honest unavailable state |
Expand by proving each boundary
The practical first release is a focused source set with clear ownership, typed destinations and testable access behavior. Reuse the search contract as the experience grows, while qualifying every new source and audience separately.
The architectural principle is straightforward: search helps discover a candidate; the authoritative access boundary decides whether its content can be released. Keeping those responsibilities separate makes the solution easier to extend and easier to reason about.
An educational technical article. Examples are illustrative, not a disclosure of proprietary implementations.