delivered for clients · names withheldAI rollout AI and agents

Enterprise search and RAG that respects document permissions

Cohash builds enterprise search and retrieval-augmented generation that only returns what each user is allowed to open in the source system. We capture permissions with every chunk at ingestion, filter by the user's groups before ranking, keep permission changes and deletions in sync, and run leak tests with accounts from different roles. Where a platform already enforces permissions natively, we use it instead of building our own.

  1. 01Sources and permission models
  2. 02Ingestion with ACLs
  3. 03Filter before ranking
  4. 04Keep permissions in sync
  5. 05Evals and leak tests
  6. 06Citations and logging
case-study / enterprise-rag-with-permissions delivered
beforeA RAG demo on one shared index afterPermission-aware retrieval in production
01 · SOURCES AND IDENTITY 02 · INGESTION WITH ACLS 03 · RETRIEVAL 04 · ANSWERS AND AUDIT SharePoint: groups · sharing links SharePoint groups ·sharing links Confluence: space and page restrictions Confluence space and pagerestrictions File shares: NTFS rights File shares NTFS rights Identity provider: Entra ID or Okta groups Identityprovider Entra ID orOkta groups ACL-aware ingestion: chunk + allowed users and groups ACL-aware ingestion chunk + allowed usersand groups Permission sync: change events · re-crawls Permission sync change events ·re-crawls Permission-aware index: ACL fields per chunk Permission-awareindex ACL fields per chunk Group-filtered search: vector + keyword, filter first Group-filteredsearch vector + keyword,filter first LLM with citations: Claude · OpenAI · Bedrock LLM with citations Claude · OpenAI ·Bedrock Query audit log: user · documents · model Query audit log user · documents ·model Leak tests in CI: role-based test accounts Leak tests in CI role-based testaccounts
case file

The story

Told without the client's name or anything that could identify them.

what happened

A professional services firm's AI team had a RAG demo that answered from one shared vector index, and in testing it quoted a document the person asking couldn't open in SharePoint. Nobody could say how a permission change in Confluence, or a leaver's private files, would reach the index. We started by listing each source and how it expresses access, then rebuilt ingestion so every chunk carries its allowed users and groups. Queries now filter by the user's groups before ranking, permission changes sync on a freshness target security agreed to, and leak tests with accounts from different roles run in CI on every change.

why it was urgent

OWASP's LLM08:2025 Vector and Embedding Weaknesses names unauthorized access and data leakage through embeddings, and recommends permission-aware vector stores. Microsoft's Copilot connectors attach an access control list to every indexed item. A first RAG demo on one shared index rarely does either.

problem statement
  • openIn the demo, the answer came from a SharePoint document the asker wasn't allowed to open.
  • recurringEvery document lands in one vector index with no record of who may read it.
  • blockedSomeone left the company and their private files still show up in answers.
  • openSecurity asked how a permission change in Confluence reaches the index, and nobody knew.
architecture

The estate, before and after

before
before

Before: a RAG demo on one shared index

A bulk job copied SharePoint, Confluence and file share content into one vector index and lost the permissions along the way. Everyone's questions hit that same index, so an answer could quote a document the person asking wasn't allowed to open.

Before: a RAG demo on one shared index A bulk job copied SharePoint, Confluence and file share content into one vector index and lost the permissions along the way. Everyone's questions hit that same index, so an answer could quote a document the person asking wasn't allowed to open. 01 · SOURCES 02 · INGESTION 03 · INDEX 04 · ASSISTANT documents pages files chunks · embeddings question similarity search SharePoint groups · sharing links Confluence space and pagerestrictions File shares NTFS rights Bulk ingestion job permissions dropped Shared vector index no record of who may read Any employee same results for everyone RAG demo app LLM answers, no citations
Read the diagram as text
  1. SharePoint → Bulk ingestion job: documents
  2. Confluence → Bulk ingestion job: pages
  3. File shares → Bulk ingestion job: files
  4. Bulk ingestion job → Shared vector index: chunks · embeddings
  5. Any employee → RAG demo app: question
  6. RAG demo app → Shared vector index: similarity search
after
after

After: retrieval filtered by each user's groups

Every chunk carries its allowed users and groups from ingestion onward, and a sync job tracks permission changes and deletions. At query time the user's groups come from the identity provider, filtering happens before ranking, and answers are cited and logged.

After: retrieval filtered by each user's groups Every chunk carries its allowed users and groups from ingestion onward, and a sync job tracks permission changes and deletions. At query time the user's groups come from the identity provider, filtering happens before ranking, and answers are cited and logged. 01 · SOURCES AND IDENTITY 02 · INGESTION WITH ACLS 03 · RETRIEVAL 04 · ANSWERS AND AUDIT documents pages files permission changes chunks with ACLs ACL updates · deletes user groups filtered query permitted chunks query log leak tests SharePoint groups · sharing links Confluence space and pagerestrictions File shares NTFS rights Ex Identity provider Entra ID or Oktagroups ACL-aware ingestion chunk + allowed users andgroups Permission sync change events · re-crawls Permission-aware index ACL fields per chunk Group-filtered search vector + keyword, filterfirst LLM with citations Claude · OpenAI ·Bedrock Query audit log user · documents · model Leak tests in CI role-based test accounts
Read the diagram as text
  1. SharePoint → ACL-aware ingestion: documents
  2. Confluence → ACL-aware ingestion: pages
  3. File shares → ACL-aware ingestion: files
  4. SharePoint → Permission sync: permission changes
  5. ACL-aware ingestion → Permission-aware index: chunks with ACLs
  6. Permission sync → Permission-aware index: ACL updates · deletes
  7. Identity provider → Group-filtered search: user groups
  8. Group-filtered search → Permission-aware index: filtered query
  9. Group-filtered search → LLM with citations: permitted chunks
  10. LLM with citations → Query audit log: query log
  11. Leak tests in CI → Group-filtered search: leak tests
results

What the client got

What changed for the client once the work was done. Described, not scored: we don't publish client figures.

  1. result 01

    Answers only use text the user may open

    We filter vector and keyword search to the user's groups before ranking. If the user couldn't open a chunk at the source, the model never sees it.

  2. result 02

    Every chunk carries its source permissions

    We store allowed users and groups with stable identity provider IDs at ingestion, resolve nested groups, and hold back documents whose permissions are unclear.

  3. result 03

    Permission changes and deletions reach the index

    Where a source sends change events we listen for them. Where it doesn't, we re-crawl on a schedule. Each source has a freshness target that security signed.

  4. result 04

    Leaks are tested on every change

    Accounts from different roles ask for content they shouldn't see, alongside retrieval quality evals on real questions, in CI.

  5. result 05

    Every answer is cited and logged

    Answers link back to their sources. We log who asked, which documents came back and which model answered, and keep those logs exactly as long as the sources themselves.

what can go wrong

Risks we plan for

  1. Stale permissions

    When ACLs refresh only nightly, someone whose access was revoked can keep retrieving content for hours. How long that window is allowed to be is a decision the sync design has to make.

  2. Aggregation leaks

    Permitted fragments can still add up. Take a few drafts, each readable on its own, and together they might reveal a reorg plan. Filtering won't catch it. Sensitivity labels and source exclusions do.

  3. Instructions hidden in documents

    Some retrieved documents carry text written to steer the model. We treat retrieved content as data and limit which tools the model can call. Prompt injection cases go into the test set.

  4. Embeddings as a copy of the data

    Your vectors and chunks are one more copy of confidential content. Give them the same encryption and residency rules as the originals, and delete the chunks when an original is deleted.

ai in this move

Where AI helps, and where it needs guardrails

In a lot of cases the platform already enforces permissions. Copilot connectors filter by source ACLs, and federated connectors fetch live through MCP under the user's own OAuth sign-in. For custom RAG, we expose retrieval as an MCP tool that only accepts audience-bound, user-delegated tokens, as the MCP authorization spec expects. An agent can't search with more rights than the person who asked.

forward deployed engineers →
you keep

What you're left with

We write these for your setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.

  • inventory01

    Source inventory with each permission model and an index-or-federate decision

    yours to keep
  • code02

    Ingestion pipeline that stores ACLs with every chunk

    yours to keep
  • document03

    Query-time filtering tied to identity provider groups

    yours to keep
  • tests04

    Retrieval eval set and leak tests running in CI

    yours to keep
  • evidence05

    Query and retrieval audit logging with retention rules

    yours to keep
field notes

Learn the background

Terms from this page in plain English. If you want the why, the field note behind it is right there.

01Prompt injection
Instructions tucked into content an AI reads, like a document or a ticket comment, meant to make it do something its user never asked for.in context →
02RAG
Retrieval-augmented generation, or RAG. A search first pulls relevant passages from your documents, and a language model writes the answer from those passages.in context →
01 Telemetry feedback loop failures feed the golden set 02 Citations and refusals cite chunks, refuse guesses 03 Eval harness in CI blocks merges on regression 04 Hybrid retrieval BM25, dense, reranker 05 ACL-aware ingestion re-embed on update, tombstones
field note · 9 min · 3-question check RAG in production: what actually breaks the ideaWhat makes a RAG assistant dependable is everything around the model. read the note
talent and delivery · permission-aware retrieval in production

Certified engineers, wherever you need them.

Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.

Onsite

Engineers at your sites in the US

Nearshore

Overlapping hours with US teams

Offshore

Overnight progress on your backlog

All time zones

Coverage handed over across time zones

24-hour coverage · US Central time
OnsiteUS business hours
Nearshoreoverlapping US hours
Offshoreovernight progress
Combinedhandover, not hand-off
01Should we build our own RAG or use Copilot or a platform search?

If your content lives mostly in Microsoft 365 or one data platform, its built-in search usually enforces permissions with less work. Custom RAG makes sense when sources span systems those tools don't cover, or when answers must follow your own rules.

02Which vector database should we use?

One that filters on metadata at query time and meets your hosting rules. Most mainstream vector stores can. Spend the energy on the permission design instead.

03How do you prove nothing leaks?

Nobody can prove a negative. You can test hard, though. We run leak tests on every change, using accounts from different roles, and we log what each query retrieved so any leak can be traced back.

04Do you also clean up the permissions underneath?

Yes. Most leaks we find trace back to broad sharing in the source system. Cleaning that up with the identity and content owners is often the first useful thing we deliver.

sources 4 sources linked last checked 2026-10-20 content fingerprint 7d631a81
  1. 01OWASP: LLM08:2025 Vector and Embedding Weaknessesgenai.owasp.org ↗
  2. 02Microsoft Learn: Copilot connectors overviewlearn.microsoft.com ↗
  3. 03Model Context Protocol: Authorization (2026-07-28)modelcontextprotocol.io ↗
  4. 04OWASP Top 10 for LLM Applications 2025genai.owasp.org ↗
Reviewed by the Cohash team Product names are trademarks of their owners. how we handle facts and data →
next step

Planning this move?

A 30-minute working session with a senior engineer. No slides.

useful to bring
  • The platform and the version you're on
  • Where you need to get to, and by when
  • What's custom: rules, plugins, integrations
  • Any audit finding or deadline driving it