Skip to main content
Memvid supports permission-aware retrieval by storing ACL metadata on every frame (chunk) and enforcing it inside retrieval (search/ask) in memvid-core. This unlocks:
  • Strict multi-tenant isolation (no cross-tenant leakage)
  • RBAC (roles/groups/principals) at frame/chunk level
  • A single .mv2 per environment with metadata-based enforcement (recommended)

Mental Model

  • A frame is the atomic unit of retrieval in Memvid. When you ingest a PDF, Memvid creates many frames (chunks).
  • ACL is evaluated per frame, so “chunk-level ACL” means “frame-level ACL metadata”.
  • ACL is not keyword-based: it does not guess who can see content. You decide the policy at ingest time.

ACL Metadata (Ingest-Time)

Attach the following keys in the frame metadata (stored on disk in the frame’s extra_metadata):
In Node/Python SDKs you can provide string[] values directly for acl_read_*. The SDK will normalize and persist them in a canonical form for the core evaluator.ACL strings are normalized (trimmed + lowercased). Treat role/group/principal identifiers as case-insensitive.

Example: Role-Restricted Chunk

If acl_visibility is "restricted" and you provide no acl_read_roles / acl_read_groups / acl_read_principals, the chunk will be denied for everyone in enforce mode.

ACL Context (Query-Time)

At query time you provide the caller identity via acl_context / aclContext: And choose an enforcement mode:
  • audit: evaluate ACL but do not block results (migration/testing)
  • enforce: filter results; deny-by-default for missing/invalid ACL metadata
Do not accept acl_context from untrusted clients. Build it server-side from your auth system (JWT claims, your RBAC store, etc.) so users cannot self-assign roles.

Creating an ACL-Scoped API Key (Dashboard)

In the Memvid dashboard:
  1. Go to API Keys and click Create Key
  2. Enable ACL scope
  3. Set Tenant ID (required for strict isolation)
  4. Optionally set Roles, Group IDs, and Subject ID
  5. Choose enforcement mode: audit or enforce
For most apps, keep the API key as a server-side credential and compute the end-user acl_context from your auth system on every request.

End-to-End (Node.js)


End-to-End (Python)


Chunk-Level Guarding (Example Policy)

You decide which chunks are restricted to which readers at ingest time. Example policy:
  • Pages 1-20: role=finance
  • Pages 21-30: role=hr
  • Pages 31+: principal=matt
To implement this, you ingest via put_many() / putMany() with per-chunk metadata (rather than a single put_file() metadata applied to all chunks).
If you use put_file(...) with metadata=..., the same ACL metadata is applied to every produced chunk. That’s perfect for document-level ACL, but not enough for section/page-level ACL.

Single .mv2 vs One .mv2 Per Tenant

Single .mv2 per environment (recommended):
  • Store all tenants in one file
  • Always set acl_tenant_id on every frame
  • Always pass acl_context.tenant_id at retrieval
  • Use restricted + allow-lists for sensitive frames
One .mv2 per tenant (simpler operations, more files):
  • Easier isolation boundaries
  • More operational overhead (more files to manage, ticketing/capacity per file)