Your RAG assistant will quote a restricted board memo to an intern if nothing between the index and the model checks who is asking. RAG access control means carrying native file permissions onto every chunk, keeping them synchronized, resolving entitlements at query time, and failing closed on uncertainty. Hammerspace’s high performance data platform for AI supplies the authoritative source layer. Your application enforces the rest.
Why Don’t Embeddings Carry Your File ACLs?
Embeddings don’t carry ACLs because chunking and embedding create new derived objects that the source file system never sees. Those chunks have permissions only if your pipeline copies them on purpose, keeps them in sync with the source, and enforces them before content reaches the model.
A file on an NFSv4 export or SMB share has an owner, a group, an ordered list of access control entries, and often a classification tag. When an ingestion job reads that file, splits it into chunks, and writes vectors into an index, none of that security context travels by default. In many deployments, the index runs under a service account that can read everything.
That gap produces three distinct failures:
- Leakage at retrieval: similarity search ranks chunks by relevance, not entitlement, so the most relevant chunk wins even when the user has no right to see it.
- Staleness: permissions change at the source after indexing, and the chunk keeps the old, wider view.
- Orphans: a file is deleted or moved, but its chunks, lexical postings, and cached answers persist.
No single feature closes this gap. “Add a metadata filter” handles part of the leakage problem and none of the staleness or orphan problems.
What you need is an authorization control plane: every control assigned to a specific layer (data platform, ingestion, retrieval, application, audit), with a named owner and a defined failure behavior. The sections below walk through each layer in order.
What Does the Data Platform Govern vs. What Must the RAG Application Enforce?
The data platform governs the authoritative record: where files live, what permissions and classification they carry, and which boundaries they are allowed to cross. The RAG application enforces access by resolving who is asking, filtering retrieval, refusing safely, and screening output. Metadata preservation is necessary but not sufficient.
Here is the responsibility split, stated plainly.
Data platform layer (Hammerspace’s role):
- Presents one global namespace over existing storage through NFSv4.2/pNFS, SMB, and S3, using native Linux clients with no client install.
- Assimilates metadata from existing storage in place, so permissions and attributes are read from the source rather than re-created in a new silo.
- Combines POSIX, storage, and usage metadata with custom tags (classification, program, residency) that ingestion reads.
- Applies file-granular Service-Level Objectives and placement policy so sources and staged copies stay in approved locations.
- Keeps a consistent path and identity for each file, which audit records join against.
Application layer (your team’s role):
- Authenticates users and agents, and resolves group memberships, clearances, and tenancy.
- Normalizes and stamps ACL and classification metadata onto every chunk, then syncs and purges it.
- Applies mandatory authorization filters inside every retrieval query and runs a final per-chunk check.
- Handles refusal messaging, output screening, agent scoping, and retrieval-event logging.
Hammerspace does not perform retrieval-time authorization, filter vector queries, handle refusals, or screen model outputs. Its job is to make the inputs to those decisions authoritative, consistent, and traceable.
End to end, the control plane runs: source namespace, ingestion (stamp, sync, purge), dense and lexical indexes, retrieval with a mandatory filter and final check, model, output screening, audit log. The platform/application boundary sits between the source namespace and ingestion. Placement policy reaches across that boundary to govern where data is staged, but every enforcement decision stays on the application side.
Where Should RAG Authorization Get Its Source of Truth?
Every RAG authorization decision should trace back to one authoritative, standards-based record of a file’s permissions and classification. If you cannot trace a chunk’s ACL to a specific source file and its current effective permissions, you cannot trust that ACL or defend it in an audit.
The hard part is that enterprise file estates speak several permission dialects at once:
- NFSv4 ACLs are ordered lists of ALLOW and DENY entries with principals expressed as user@domain strings. The semantics are defined in IETF RFCs, including RFC 8881, with NFSv4.2 extensions in RFC 7862. Order matters: an earlier DENY entry blocks access that a later entry grants.
- SMB uses security descriptors keyed to Windows SIDs, with inherited entries and a canonical ordering that places explicit entries before inherited ones and deny before allow within each group.
- S3 uses bucket and identity policies evaluated as documents, where an explicit deny overrides any allow.
Reconciling these is a real normalization problem, not a formatting exercise. Ingestion has to translate every source into one canonical principal space and preserve deny semantics. A common mistake is flattening everything into an “allowed groups” list and dropping DENY entries, which silently widens access. When a file’s effective permissions cannot be computed with confidence, index it as restricted or skip it.
A unified, standards-based layer shrinks this problem. When sources are presented through a single global namespace for AI and enterprise data, ingestion reads permissions through documented protocol interfaces instead of several proprietary APIs.
That is the practical case for open standards over proprietary storage stacks: authorization inputs are auditable because their semantics live in IETF RFCs, not in a vendor’s private format, which gives your team a documented reference for permission mapping. Hammerspace’s actionable metadata and policy engine adds the classification and custom tags your pipeline stamps alongside the ACL.
Protocol fidelity is core engineering here, not an add-on. The Hammerspace team includes Trond Myklebust, Tom Haynes, Brian Pawlowski, and CEO David Flynn, the people who built Linux NFS itself.
How Do You Stamp, Sync, and Delete Chunk-Level ACL Metadata?
Every chunk needs a metadata contract: a pointer to its source file, a normalized ACL that includes denies, a classification label, a tenant, and a version stamp tied to the source. RAG permission sync keeps that contract true as permissions change and files are deleted.
The chunk metadata contract
Stamp these fields on every chunk and every lexical posting:
- source_id: stable file identifier plus namespace path.
- source_version: content hash or modification time, plus a hash of the effective permissions at ingestion.
- allow_principals: normalized principal identifiers.
- deny_principals: normalized, evaluated before allows.
- classification: label plus any handling caveats.
- tenant_id: the isolation boundary the chunk belongs to.
- boundary: the site, cloud, or enclave the content is permitted to reside in.
- acl_verified_at: timestamp of the last successful permission check against the source.
- pipeline_version: which ingestion and normalization logic produced the record.
Stamp every chunk from a document with that document’s effective ACL. Do not infer finer-grained permissions from content. A document-level security RAG design is only as granular as the source permissions that actually exist.
Keeping permissions current
A permission change at the source must reach every chunk derived from that file. Run two mechanisms: event-driven updates give you speed, and scheduled reconciliation, which compares source permission hashes against the index, catches missed events. Both are pipeline responsibilities.
Define a maximum staleness window. When acl_verified_at falls outside it, the retrieval layer treats the chunk as unauthorized until reconciliation re-verifies it.
Deletion propagates everywhere
Deletion has to reach every place derived content lives:
- Dense vector indexes. Many ANN implementations handle deletes as soft deletes, marking entries removed while vectors remain until rebuild or compaction. In Postgres, deleted rows persist as dead tuples until VACUUM reclaims them.
- Lexical indexes. Segment-based keyword engines mark deleted documents and physically drop them only at merge.
- Caches: retrieval result caches, semantic caches, and cached answers.
- Secondary copies: staged corpora, evaluation sets, and fine-tuning datasets.
Purge by source_id across all of them, then run a verification query that must return zero results.
How Does RAG Access Control Work at Query Time?
At query time, the application authenticates the real caller, resolves current entitlements, pushes a mandatory filter into every retrieval query, re-checks each candidate chunk, and fails closed on any uncertainty. The model only sees chunks that passed both checks. That is permission-aware retrieval in practice.
The request-time control flow
- Authenticate the end user, not just the service. When an application or agent acts for a user, use on-behalf-of delegation such as OAuth 2.0 Token Exchange (RFC 8693), so the downstream token carries both the user subject and the acting party.
- Resolve entitlements: transitive group membership, clearances, tenant, and program access. Cache briefly and record an entitlement snapshot ID.
- Build the authorization filter server-side from resolved entitlements. Never accept filter values from client parameters or from the prompt.
- Apply the filter inside both the dense and lexical queries, before ranking and before any dense-plus-lexical result fusion.
- Run a final check on each candidate: deny list, classification against clearance, tenant match, and staleness window.
- Assemble context from passing chunks only, carrying source_id for citations.
- Write the retrieval-event record (covered below).
Fail-closed rules
Fail-closed retrieval means uncertainty resolves to “no access.” Encode these as explicit rules:
- Identity provider or entitlement service unreachable: return no retrieved content.
- Chunk missing allow list, tenant, or classification: exclude it.
- acl_verified_at outside the staleness window: exclude it.
- Filter construction error: abort the query. Never retry unfiltered.
- Unrecognized principal format after normalization: exclude it.
Refusal messaging that doesn’t leak
A refusal should confirm nothing. Respond with something like “I couldn’t find information you have access to on that topic.” Avoid naming restricted documents, reporting how many results were withheld, or suggesting who holds access. Keep response shape consistent between “nothing exists” and “everything was filtered,” so users cannot probe for the existence of restricted material.
How Do You Enforce Vector Database Access Control and RAG Multi-Tenant Isolation?
Enforce tenant and classification boundaries structurally where you can, with separate indexes or databases, and use row-level filtering within a boundary. Then harden the retrieval service so nothing reaches the index without passing through the authorization path.
Isolation trade-offs
- Separate index or database per tenant or classification level: strongest isolation and easiest to reason about, with more operational overhead.
- Shared index with namespaces or partitions: lighter to operate, but depends on correct partition selection on every query.
- Shared index with metadata filters only: most flexible and weakest, because a single filter bug crosses tenants.
For classification segmentation in federal and regulated environments, use a physically separate index per enclave. RAG multi-tenant isolation that relies only on filters is a policy, not a boundary.
Filtered ANN has a recall caveat. Post-filtering an approximate search returns fewer than k results, or none, when the permitted set is small relative to the index. Teams sometimes “fix” this by loosening the filter, which is exactly wrong. Instead, enlarge the candidate pool, use filter-aware or iterative index scans, or partition by tenant.
A database-enforced pattern
One illustrative pattern is Postgres row-level security with pgvector, where a policy compares each chunk’s allow list to a transaction setting holding the caller’s principals. It is not the only correct approach, and the PostgreSQL row security documentation spells out the caveats:
- Superusers and roles with BYPASSRLS always bypass policies. Table owners bypass them unless FORCE ROW LEVEL SECURITY is set. Run retrieval as a non-owner role without BYPASSRLS.
- Scope caller context per transaction with SET LOCAL or set_config with the local flag. Session-level settings on pooled connections leak to the next request that borrows the connection.
Service hardening
Restrict index access at the network layer. Use separate credentials for ingestion (write) and retrieval (read, filtered). Block direct access from notebooks and admin tools, and add CI tests that run cross-tenant queries that must return zero rows.
How Do You Keep Regulated Data Inside Approved Boundaries Across Sources, Staging, and Indexes?
Governance has to follow data into every derived artifact: staged copies, chunk stores, embeddings, lexical indexes, and caches. File-granular placement policy keeps regulated sources and staged copies inside approved sites, clouds, or enclaves, even when they are accelerated for AI, and your application team places indexes and caches under the same rule.
Treat an embedding as carrying the sensitivity of the text it came from. If a source file cannot leave an enclave or a residency region, neither can its chunks, vectors, or cached answers.
On the source side, Hammerspace Global Data Services applies one set of policies at file granularity. Service-Level Objectives define where a file is allowed to reside and at what protection level, and custom tags such as classification or residency drive those decisions automatically. Data Orchestration executes tiering and migration in the background, even on live data.
Acceleration stays inside the boundary too. Consider a defense program where files tagged for a specific enclave are pre-staged to GPU-local NVMe through Hammerspace Tier 0 on that enclave’s cluster, but policy never permits replication to a commercial cloud region. That same tag flows into each chunk’s boundary field, so the application team places the resulting indexes under the same rule.
Be precise about ownership. Placement policy governs data within the namespace, while indexes and caches written to systems outside it are placed by your application team. For the broader framework beyond retrieval, see our companion piece on unstructured data governance at petabyte scale.
What Should RAG Audit Logging Record to Answer “Who Saw What, and Why”?
A useful RAG audit log records every retrieval event: who asked, on whose behalf, which entitlements applied, which chunks were returned, and which authoritative source files those chunks came from. Lineage shows where data went. Retrieval records show who actually saw it.
Lineage-only audit is a common gap. Knowing that a file was embedded into an index says nothing about which users later received its contents. Define a retrieval-event record with these fields:
- request_id and timestamp.
- User subject and acting agent or service, taken from the delegated token.
- Entitlement snapshot ID used for filtering.
- Query hash, or a redacted query per your retention policy.
- Indexes queried and a hash of the applied filter.
- Returned chunk IDs, each with source_id and source_version.
- Count of candidates removed by the final check (internal only, never shown to users).
- Model response ID, output screening verdict, and refusal flag.
What makes the record useful is the join. Because each source_id resolves to a path in one consistent namespace, an investigator moves from “user X received chunk Y” to the exact file and the permission hash captured at ingestion. Store these logs as protected data, since queries and prompts often contain sensitive content themselves.
How Do Prompts, Outputs, and Agents Change RAG Authorization?
Document permissions are only one surface. Prompts carry sensitive data in, outputs carry it out, and agents take actions with delegated authority, so each needs its own control. The OWASP RAG Security Cheat Sheet, part of the OWASP Cheat Sheet Series, is a useful reference for these emphasis areas: access control over retrieved content, protection of the vector store, treating retrieved text as untrusted input, and output handling. The OWASP Top 10 for LLM Applications also treats vector and embedding weaknesses as a distinct risk category.
- Prompts: never let prompt text alter authorization filters, and classify prompts before logging them to lower-trust stores.
- Retrieved content: treat it as untrusted input. Instructions embedded in a document must not change tool permissions or filters.
- Outputs: screen for classification markings and sensitive identifiers, and confirm every cited source is one the caller can access.
- Agents: grant least-privilege tools, delegate with token exchange, authorize each action, and apply the same fail-closed rules as retrieval.
Reference checklist by control-plane layer
Here is every control covered above, mapped to the layer that owns it.
Data platform (Hammerspace):
- One namespace over NFSv4.2/pNFS, SMB, and S3, with native Linux clients and no client install.
- Metadata assimilated in place, with classification and residency tags.
- File-granular placement for sources, staging, and Tier 0.
- Stable file identity for audit joins.
Ingestion (application):
- Normalize ACLs across protocols, preserving denies.
- Stamp the full chunk contract.
- Run event-driven RAG permission sync plus reconciliation.
- Purge all derivatives by source_id and verify.
Retrieval (application):
- Server-side filters in dense and lexical queries.
- Final per-chunk check and fail-closed rules.
- Non-leaking refusals.
- Structural isolation, with RLS bypass and pooling caveats handled.
Application and audit:
- RFC 8693 delegation, output screening, and scoped agents.
- Retrieval-event records joined to authoritative sources, stored as protected data.
Strong RAG access control starts with an authoritative, standards-based source of truth and ends with enforcement your application owns end to end. Hammerspace provides the data platform layer: a Unified Data Plane over open protocols, Global Data Services for metadata assimilation and file-granular policy, Data Orchestration across sites and clouds, and Tier 0 for GPU-local acceleration inside approved boundaries. To discuss how that layer fits your RAG data governance design, contact Hammerspace or call +1 (650) 777-8728.
Frequently Asked Questions
How do you enforce access control in RAG?
Enforce it across layers rather than relying on one feature. Ingestion preserves each file’s native permissions and stamps them onto every chunk. At query time, the application resolves the real caller’s current entitlements, builds an authorization filter on the server, and applies it inside both dense and lexical searches before ranking. A final per-chunk check confirms deny entries, classification, tenant, and freshness, and anything uncertain is excluded before the model sees it.
Do vector embeddings inherit file permissions?
No. Chunking and embedding create new derived objects that the source file system does not track, so NFSv4, SMB, or S3 permissions stay attached to the original file only. Indexes often run under a broadly privileged service account, so similarity search will return restricted content based on relevance alone. Your pipeline has to copy normalized allow and deny principals, classification, and tenant onto each chunk, then keep those fields synchronized with the source.
What should a RAG system do when it can’t verify a user’s current permissions?
It should fail closed and return no retrieved content. It should not fall back to cached broad access or run an unfiltered search. The same rule applies to chunks with missing security metadata or a verification timestamp outside the allowed staleness window. The user should get a neutral response that does not reveal whether restricted material exists, and the system should never retry a failed filtered query without the filter.
How do you keep a RAG index in sync when file permissions change or documents are deleted?
Pair event-driven updates, which push permission changes quickly to every chunk derived from a file, with scheduled reconciliation that compares source permission hashes against the index to catch missed events. Set a maximum staleness window so chunks that haven’t been re-verified are treated as unauthorized. For deletions, purge by source identifier across vector indexes, keyword indexes, caches, and secondary copies such as evaluation or fine-tuning sets. Then run a verification query that must return zero results, since soft deletes and pending compaction or merges can leave data physically present.
How do you prevent cross-tenant retrieval in a shared vector database?
Separate indexes or databases per tenant give the strongest isolation. Shared indexes with partitions depend on correct partition selection on every query, and filter-only designs are the weakest. If you use database-enforced controls such as Postgres row-level security, run retrieval as a non-owner role without bypass privileges. Scope caller context to each transaction so pooled connections never carry a previous request’s identity. Back this up with separate read and write credentials, no direct notebook or admin access to the index, and CI tests that run cross-tenant queries and must return nothing.
What should RAG audit logs record?
Each retrieval event should capture the requesting user, any acting agent or service, the entitlement snapshot used, a hash of the applied filter, and the indexes queried. It should also list the returned chunk IDs along with their source file identifiers and versions. Include the output screening verdict, the refusal flag, and an internal-only count of candidates removed by the final check. Lineage alone only shows that content was indexed, so these records are what prove who actually received it. Store the logs as protected data and hash or redact query text according to your retention policy.
Where does the storage platform’s responsibility end in RAG security?
The storage platform is responsible for making authorization inputs authoritative, consistent, and traceable. That covers permissions, classification tags, placement within approved boundaries, and stable file identity for audit joins. It does not authenticate users, filter vector queries, handle refusals, or screen model outputs, because those decisions belong to the RAG application. Indexes and caches written to systems outside the platform’s namespace also fall to the application team, which should place them under the same boundary rules as their source files.
