It inherits permissions from your source systems (Drive, SharePoint, your CRM, and more) and keeps them in sync as those change. Enforced in the index, so a prompt can't argue past it. MCP-first, Apache-2.0.
$ ./deploy/demo.shDemo tenant: c1e6…9b42 sales-bot + support-bot → account:acme · eve-bot → account:globex (same org principal — entity scope is the only difference)4) Provable scoping: eve-bot attacks acme's data recall for acme's quote -> 0 results brief of account:acme -> 0 items write tagged to acme -> HTTP 403 tampered scope handle -> HTTP 401Same org credential, different entity scope — enforced in the index, not in the prompt.
Provable scoping 0 results · 403 · 401
An agent talking to customer A can never surface customer B's pricing. In-index pre-filters enforce that, not the model, so injection can't widen visibility.
Live truth 31ms CDC-to-queryable
A source change is a deterministic keyed upsert that retires the old value structurally: no LLM in the structured write path, and bi-temporal history stays intact.
Inner-loop speed <50ms p95 core · sub-ms get
Every retrieval path stays inside the 50ms p95 envelope in the serving core at 1M chunks, encoder included; permissioned point reads are sub-millisecond end-to-end. The served HTTP path (~105ms p95 on a real 115k-chunk workspace) and the QPS ceilings are measured too, never quoted: the honesty log.
When you actually need this
The login-and-chat-about-your-own-account bot is the easy, already-solved case. One user, one account, one system; a WHERE account_id = you handles it.
Verity is built for the harder region next to it: many agents, many customers' data in reach of one authorized agent, many sources, permissions that change, freshness that matters, and needing to prove something can't leak.
Empty checkout to a permission-filtered query. --visibility is required. Visibility is never guessed, and anything arriving without it is quarantined.
cargo run --release -p verity-cli -- dev# compose up + server + tenant + scope handleverity-cli add ./docs --visibility 1 # ingest a directory (visibility is never guessed)verity-cli query"what do we know about pricing?"# scoped hybrid recall with provenance tags
The five-minute walkthrough, including watching a second agent get 0 results on the same data and then wiring an agent over MCP, is Get started →. Run the packaged demos yourself. demo/two_agent_trust.py proves the trust boundary through the real MCP interface: one agent sees a group-shared doc because Verity resolves its nested Google-group membership, while the other stays dark even under prompt-injection. demo/backup_restore_drill.sh proves a byte-identical backup/restore round-trip.
Works with your stack. Six framework adapters (LlamaIndex · LangChain · LangGraph · CrewAI · Google ADK · OpenAI Agents) · MCP (14 tools) for every other agent · sources from HubSpot, Google Drive, Gmail, Salesforce, Postgres/Debezium, Google Workspace + Microsoft Entra directory syncs, minted webhooks and files. Connect a system → or read the ingestion doors →. BYOT: bring your own token; the only credential Verity issues is its own scope handle.
How it works
Writes converge on one structural choke point; reads never wait on an authorization service. Correctness and speed come from the same design: precomputed scope filters are also the fastest filters.
Bi-temporal L0/L1
Every write lands first in L0, an immutable evidence log with lineage from day one; it powers audit, poison rollback, and lineage-driven erasure. L1 holds canonical records with valid_from/valid_to: a CRM row stays a row, an update structurally retires the old value, and as_of reads reconstruct any past state. No LLM ever touches the structured write path.
Scope handles
Source ACLs and directory identity resolve into a SpiceDB ReBAC graph, nested groups included: a doc shared with a Google Group resolves to its transitive members, proven live against a real Google Workspace directory. A session mints an HMAC-signed scope handle (principals, entity scope, confidentiality ceiling) and every read carries it. Handles are compiled ahead of time: the read path makes zero live authorization calls.
In-index enforcement
The scope is a mandatory pre-filter inside the index query itself: filter-then-rank, never truncate-then-authorize. An empty principal set matches nothing (fail-closed). A tampered handle is a 401. Prompt-injected query text is just text. There is no post-hoc filtering step to forget.
Knowledge layer
Cross-customer learning ("healthcare deals need DPA redlines") is a privilege, not a recall default: candidates publish only past a deterministic de-identification gate, k-distinct-entity support (k ≥ 3), and human review. The teaser is below.
Where it runs. One central, multi-tenant server holds all memory and every scope decision; verity-mcp is a thin stateless front door you run per identity. Architecture & deployment →
Every fact you ever read from Verity carries its ACL provenance:
mirroredapproximatedadmin-assignedquarantined,
so "how much do I trust this filter" shows up on every hit instead of buried in the docs.
the generalized knowledge layer
Learns across your customers. Never leaks them.
An agent scoped to one customer can notice a pattern but structurally cannot know it's a pattern. Verity's answer: a generalization becomes an entity-free knowledge item that publishes only after de-identification, k-distinct-entity support, and human review. It is the one thing that crosses scopes safely, because it is de-identified and human-gated. No OSS memory system (Mem0, Zep, Letta) does cross-customer learning at all.
Measured precision-first, on the most trust-sensitive thing Verity does: precision 1.000 / recall 0.862, 0 false merges across 112 negatives on the live-judged eval, and a generalization needs ≥3 distinct customers before it can publish. Precision is the guarantee; recall is the capability we keep raising.
The worked DPA example, the full eval set, the gates, the merge cascade, and the retrieval carve-out: the knowledge layer docs →
No generative LLM and no live authorization call on the read path. The only model between an agent and its memory is a ~30M-parameter local encoder, and its latency is in every number.
Benchmarks
In the serving core, every retrieval path stays inside the <50ms p95 envelope at 1M chunks, encoder included (worst dense path ~37–48ms p95). Measured on verity-bench at a stated corpus size, selectivity, and machine, never quoted.
Measured honestly, including where it doesn't win yet. The served path (a real HTTP request, the encoder, and a live 115k-chunk workspace) is ~105ms p95, because recall is Postgres-bound (a release build barely moves it); the get path stays sub-millisecond end-to-end. And the ≥300 QPS/node target is open work: this laptop-in-Docker setup saturates ~50–120 QPS. All of it is on the log, never hidden under a hero number. The honesty log: full tables, breaches, and fixes →
Get started
Empty laptop to a scoped, leak-proof query in five minutes: boot the plane, ingest a real directory, run a permission-filtered query, watch a second agent get 0 results on the same data, and wire a live agent over MCP.