c3.3 Enforce retrieval access control with metadata filtering
Attach metadata (department, classification, tenant, dates) to each vector and filter retrieval by the requesting user's attributes, so the model only sees documents that user is authorized to see.
Implementation guidance
How to implement on AWS
Supply metadata files for each ingested document (tags, classification, business unit, timestamps) and filter queries by user attributes at query time. Use metadata to enforce classification tiers, isolate tenants, and apply temporal access. The application must set the correct filter on each Bedrock call.
The retrieval layer is an access-control boundary
In a RAG application, the model answers using whatever the retriever pulls from the knowledge base. If retrieval returns a document the user should not see, the model will happily summarize it into the answer — a data leak with no obvious trace. So retrieval is not just a relevance problem; it is an authorization boundary. Metadata filtering is how you enforce it: attach attributes (department, classification, tenant, effective dates) to each vector, then filter every query by the requesting user's entitlements.
Attach metadata at ingestion
Each source document carries a metadata sidecar (e.g. document.pdf.metadata.json) with the attributes you will filter on:
{
"metadataAttributes": {
"department": "finance",
"classification": "confidential",
"tenant_id": "acme-123"
}
}
These become filterable fields on every vector derived from that document.
Filter every query by the caller's entitlements
On Retrieve / RetrieveAndGenerate, pass a retrievalConfiguration whose filter is built from the authenticated user's attributes — never from user-supplied input. Combine conditions with andAll so all must hold:
{
"retrievalConfiguration": {
"vectorSearchConfiguration": {
"filter": {
"andAll": [
{ "equals": { "key": "tenant_id", "value": "acme-123" } },
{ "equals": { "key": "department", "value": "finance" } },
{ "notEquals": { "key": "classification", "value": "restricted" } }
]
}
}
}
}
Bedrock supports operators such as equals, notEquals, in, greaterThanOrEquals, and the boolean combinators andAll / orAll.
Build the filter server-side from a trusted identity
The security of this control rests entirely on where the filter values come from. Resolve tenant_id, department, and clearance from the caller's verified identity (the JWT claims / session), in your backend — never let the client send the filter. If a user could set their own tenant_id, the boundary is gone.
Naming note: keep metadata keys consistent across all documents; a typo (deptvsdepartment) silently excludes or leaks documents. Validate the metadata schema at ingestion.
How it fits together
Acceptance criteria
Vectors carry classification/tenant metadata; queries filter by user attributes; a test user cannot retrieve documents above their clearance or from another tenant.
Practical implementation
How this control is implemented in each reference architecture:
Each vector carries classification/tenant metadata; the Application account passes the authenticated user's attributes and the Generative AI account filters retrieval to only what that user may see.
- Supply metadata files (classification, business unit, tenant, timestamps) for each ingested document so every vector is tagged.
- In the Application account, derive the filter from the authenticated user's attributes (Cognito/Identity Center claims) and pass it on every retrieve call.
- Enforce the metadata filter on each Bedrock knowledge base query so retrieval never returns documents above the user's clearance or from another tenant.
How to validate: Vectors carry classification/tenant metadata; a test user cannot retrieve documents above their clearance or from another tenant; the filter is set server-side on every query.
Avoid: Trusting the client to send the right filter. Derive it from the authenticated identity server-side so a tampered request cannot widen retrieval.
Vectors are tagged with classification/tenant metadata and the application tier filters retrieval by the authenticated user's attributes on every query.
- Attach metadata (classification, tenant, business unit, dates) to each ingested document.
- Derive the retrieval filter from the authenticated user's claims and set it on every knowledge base query.
- Verify a user cannot retrieve above their clearance or across tenants.
How to validate: Vectors carry metadata; queries filter by user attributes; a test user cannot cross classification or tenant boundaries.
Avoid: One shared index with no per-user filter. Tag vectors and filter by identity so RAG respects the same access control as the source data.
Threats addressed
- The AI surfacing data the requesting user is not authorized to see.
- Cross-tenant data exposure in shared vector stores.
AWS services
Pricing
Metadata filtering adds no separate charge — you pay the normal knowledge base retrieval, embedding, and vector-store costs. Filtering can actually lower cost slightly by reducing the candidate set the model must process. See Configure and customize queries and response generation.
Framework mappings
OWASP GenAI/LLM Top 10 (2026)
- LLM02 Sensitive Information Disclosure
- LLM08 Hidden Context Exposure
NIST AI Risk Management Framework (AI 100-1)
- MANAGE.1 AI risks are prioritized, responded to and managed
AWS Well-Architected Generative AI Lens (Security)
- GENSEC01-BP03 Implement least privilege access to data stores
Learning resources
References
- AWS SRA for AI — Capability 3, Metadata filtering for secure retrieval
AI Security Maturity Model