Content
# HyperBus Core
[](https://pypi.org/project/hyperbus-core/)
[](LICENSE)
[](https://pypi.org/project/hyperbus-core/)
Containment for AI agent swarms: **memory access is a capability an agent
holds, not a property of where the data lives.** The framework-agnostic core
behind [HyperBus](PRD.md), built by [TenantSwarm.ai](PRD.md).
Framework-specific integration (LangGraph, Google ADK, Pydantic AI, MCP) lives in separate
adapter repos that depend on this one — see
[`specs/002-framework-adapters/spec.md`](specs/002-framework-adapters/spec.md).
## Why companies and products choose HyperBus Core
If you ship multi-agent products on LangGraph (or plan ADK / MCP), your buyers
already assume tenants cannot see each other. The harder question — and the
one most checkpointers leave unanswered — is what happens **inside** one
customer when a single agent is prompt-injected.
**Choose HyperBus when the blast radius of a compromised agent must be smaller
than the whole tenant.**
| If you adopt… | What you get | What you still lack |
|---|---|---|
| Official LangGraph Postgres / Redis / SQLite checkpointers | Durable threads | No tenant model, no agent scoping — isolation is whatever your app remembers to pass |
| `langgraph-tenancy` | Tenant-prefixed threads | Still one flat memory space per tenant; every agent can reach every checkpoint |
| LangSmith Deployment / AWS Bedrock AgentCore | Hosted tenant boundaries | Platform lock-in; still tenant-level, not per-agent region control |
| Storage-branded savers (HANA, DynamoDB, Cockroach namespace, …) | A different backend | Differentiation on where bytes live, not who inside the tenant may read them |
| **HyperBus Core + `hyperbus-langgraph`** | Structural tenant keys **and** fail-closed per-agent, per-region grants | A portable library you embed — not another control plane you migrate onto |
**Why product and platform teams pick this over the alternatives:**
1. **Containment is the product guarantee.** Competitors stop at “customers
cannot cross-read.” HyperBus adds the axis security and compliance owners
actually ask for: *support cannot address billing, billing cannot address
PII, and revoke-all is one call when an agent is burned.* Regions live in
the storage key — denial is structural, not a soft filter an LLM can talk
past.
2. **Evidence, not policy docs.** Verified in-repo: **0** cross-tenant leaks
across 198,000 exhaustive attempts; **0** false-allows across 20,000
capability checks; blast radius of a compromised support agent held to
**1/6** regions in the scorecard fixture. See
[`docs/benchmark-scorecard.md`](docs/benchmark-scorecard.md).
3. **Fits the stack you already run.** Drop in as a `BaseCheckpointSaver`
via `hyperbus-langgraph`. Same LangGraph graphs; grants and regions ride
in `config["configurable"]`. Core stays framework-agnostic so ADK / MCP
adapters do not fork isolation logic.
4. **Governance you can show an auditor.** Hash-chained audit of grants and
denials, `grants_at` for “what could this agent reach on date D?”, and a
compliance export path — without forcing a hosted control plane for the
OSS path.
5. **Honest non-pitch.** Serialization speed is an internal optimization, not
why you buy this. Tenant isolation alone is table stakes elsewhere. Adopt
HyperBus for **intra-tenant agent containment**; everything else is
supporting machinery.
Full competitive table: [How this compares](#how-this-compares). Product
framing: [`PRD.md`](PRD.md).
## Why use this (technical)
**The problem.** When you run ten agents for one customer, they share one
memory space. Every agent can read every checkpoint any other agent wrote.
Nothing in LangGraph, ADK, or MCP expresses "this agent may read that memory
and not this one," because their persistence layers are addressed by thread,
not by authority. That is fine until one agent is subverted by prompt
injection — at which point the attacker does not need to escape the tenant,
because everything valuable is already reachable from inside the agent they
compromised.
**What this does about it.** Two independent axes of access control:
1. **Intra-tenant agent capabilities (the differentiator).** A tenant's
memory divides into named regions, and each agent holds explicit
per-region read/write grants. Deny by default. Regions are part of the
storage key, so an agent confined to one region cannot *address* a
location in another — a denial is a structural impossibility, not a
rejected request. Revocation is immediate, and "revoke everything for this
agent" is one call. **Verified: 0 false-allows across 20,000 randomized
checks.**
2. **Structural tenant isolation (table stakes, done properly).** Tenant
identity is bound once at construction and is the only input to the tenant
portion of key construction — no method accepts a per-call tenant or
filter. **Verified: 0 leaks across 198,000 exhaustive cross-tenant read
attempts.**
**What this deliberately does not claim.** Tiered serialization exists and is
worth 2-3x on large embedding payloads, but measured against LangGraph's real
serializer rather than a strawman it is a *regression* below ~10,000 rows.
It is an internal optimization, not a reason to adopt this. See
[`PRD.md`](PRD.md) Section 3 for the numbers and
[Section 11](PRD.md) for what changed and why.
## What this is
A containment and isolation core, intended to sit underneath a
`BaseCheckpointSaver`-style adapter for LangGraph (and, planned, Google ADK
and MCP — see [spec 002](specs/002-framework-adapters/spec.md)):
- Enforces **fail-closed intra-tenant agent capability control** — an agent
has zero access to a memory region unless explicitly granted, and cannot
construct a key into a region it lacks.
- Enforces **structural tenant isolation** — every storage key is namespaced
by a required `tenant_id`, with no code path capable of constructing a
cross-tenant key.
- Addresses checkpoints by LangGraph's real triple `(thread_id,
checkpoint_ns, checkpoint_id)`, so subgraph state does not collide with its
parent's.
- Stores large columnar state via tiered serialization (Arrow / JSON;
FlatBuffers is specified but unimplemented).
## What this is not
- Not cross-VM / cross-host shared memory.
- Not encryption-at-rest or hardware attestation.
- Not a multi-tenant SaaS control plane — this package retains/exports audit
locally via in-process stores and `GrantControlPlane`.
- Not a LangGraph checkpointer *itself* — this is the framework-agnostic
core. The checkpointer is `hyperbus-langgraph`, a separate package that
depends on this one (see Status below).
Those are deliberately out of scope for this open-source package. See
[`.specify/memory/constitution.md`](.specify/memory/constitution.md) Article
II.4 for the full scope boundary and rationale.
## Status
Core isolation, capability enforcement, and serialization are implemented and
tested (see Stress Test Results and Test Coverage below).
**`hyperbus-langgraph` now exists** — a working `BaseCheckpointSaver` in its
own repo (constitution VII.2), verified for behavioral parity against
LangGraph's `InMemorySaver` by running real compiled graphs. The capability
layer is reachable end-to-end: a graph declares its agent and region through
`config["configurable"]`.
**Async is implemented** (`ainvoke` / `aput` / `aget_tuple` / `alist`, with
`AsyncStorageBackend` in core). **Postgres** (`PostgresBackend`, `[postgres]`)
and **Redis** (`RedisBackend`, `[redis]`) are concurrency-tested.
Market-readiness layers ship in core: blast-radius scorecard, hash-chained
audit, channel→region maps, `GrantControlPlane`, dual-control
`GrantApprovalQueue`.
The largest remaining gaps are a **public reference integration** and
upstream LangGraph awareness — see [`ROADMAP-90-DAY.md`](ROADMAP-90-DAY.md).
See [`specs/001-hyperbus-saver-core/spec.md`](specs/001-hyperbus-saver-core/spec.md)
for the current feature spec, user stories, and acceptance criteria.
## Install
```bash
pip install hyperbus-core
# Optional backends and serialization tier
pip install "hyperbus-core[postgres]"
pip install "hyperbus-core[redis]"
pip install "hyperbus-core[arrow]"
```
For LangGraph, install the adapter instead of using core directly:
```bash
pip install hyperbus-langgraph
```
See [`hyperbus-langgraph`](https://github.com/TenantSwarm-ai/hyperbus-langgraph)
for checkpointer usage. Local development: `pip install -e .` from this repo.
## Stress Test Results
Run yourself: `python examples/03_stress_test.py`. Output below is real,
captured from an actual run against the code in this repo — not simulated.
**Cross-tenant leak audit** (100 tenants × 20 checkpoints each, using
*identical* thread/checkpoint IDs across every tenant — the realistic
collision case, not random IDs designed to avoid collision):
| Metric | Result |
|---|---|
| Checkpoints written | 2,000 |
| Cross-tenant read attempts | 198,000 (every tenant vs. every other tenant, exhaustively) |
| Leaks found | **0** |
| Write time | 9.4ms |
| Audit time | 698.8ms |
**Engine throughput** (single tenant, 5,000 operations, `InMemoryBackend`):
| Operation | Total time | Throughput | Per-op |
|---|---|---|---|
| put | 28.1ms | 178,186 ops/sec | 5.6µs |
| get | 18.0ms | 277,688 ops/sec | 3.6µs |
**Capability layer under load** (200 agents × 50 regions, ~10% of pairs
granted, 20,000 randomized checks):
| Metric | Result |
|---|---|
| Checks run | 20,000 |
| Throughput | 1,111,973 checks/sec |
| False allows | **0** |
**Containment scorecard** (same session; see
[`docs/benchmark-scorecard.md`](docs/benchmark-scorecard.md)):
| Metric | Result |
|---|---|
| Blast radius (compromised support / 6 regions) | **1/6** |
| Write amplification vs LangGraph `InMemorySaver` (50 steps) | **1.009×** bytes |
| Scoped vs full channel read | ~1500× on large+small shape |
| Postgres async put p50 / p99 (local) | 2.37 ms / 6.19 ms |
| Postgres async get p50 / p99 (local) | 0.84 ms / 2.92 ms |
**Honest scope note:** InMemory figures are a floor for isolation/capability
cost. Postgres latency is one laptop + Docker Postgres 16 — not a cloud SLA.
Full filled table: `docs/benchmark-scorecard.md`.
## Test Coverage
```bash
.venv/bin/pytest tests/ --cov=hyperbus_core
```
**445 tests passing, 90% coverage** (85% floor enforced by `fail_under` in
`pyproject.toml`). Tuple round-trip (AC-4.4) is covered by the typed JSON
codec; no open serialization xfails.
- `tests/test_capability_enforcement.py` / `test_blast_radius.py` /
`test_redteam_injection.py` — containment attacks and scorecard.
- `tests/test_isolation_adversarial.py` / `test_backend_parity_adversarial.py`
— cross-tenant reads across backends.
- `tests/test_audit_integrity.py` / `test_audit_store.py` — hash chain +
`grants_at`.
- `tests/test_channel_region_map.py` — mixed-trust channel fan-out.
- `tests/test_postgres_*.py` — crash, latency, concurrency.
- `tests/test_serialization.py` — tier selection / Arrow fidelity.
- Plus engine, backend, envelope, capability, control-plane modules.
## How this compares
Honest, factual comparison — not marketing claims. Sources linked where
possible; anything unconfirmed is marked as such rather than assumed.
| | Isolation model | Enforcement | Open source | Category |
|---|---|---|---|---|
| **HyperBus Core** | Tenant ID bound once at construction, **plus per-agent grants on named regions within a tenant** | Structural on both axes — fail-closed, verified (0 leaks / 198,000 attempts; 0 false allows / 20,000 checks) | Yes (Apache 2.0) | Embeddable library |
| `langgraph-tenancy` | Tenant-prefixed thread IDs, drop-in wrapper | Covers the tenant boundary. **No intra-tenant agent scoping** — the axis this project is built around | Yes | Embeddable library |
| LangSmith Deployment / AWS Bedrock AgentCore | Tenant scoping at the platform layer | Tenant-level, not agent-level. Also platform-coupled, where this is portable across frameworks | No (hosted) | Platform |
| `langgraph-checkpoint-postgres`/`-redis`/`-sqlite` (official) | None built-in | Left to the caller passing a correct `thread_id`; no tenant concept in the checkpointer itself | Yes | Embeddable library |
| `langgraph-checkpoint-hana` (SAP) | None | Differentiates on storage backend (SAP HANA Cloud), not isolation | Yes (MIT) | Embeddable library |
| `langgraph-checkpoint-aws` | None | Differentiates on storage backend (DynamoDB/Bedrock/Valkey), not isolation | Yes | Embeddable library |
| `langchain-cockroachdb` | Opt-in namespace column, **documented for the vectorstore** — "when enabled, all CRUD and search operations are scoped to the namespace" ([source](https://docs.langchain.com/oss/python/integrations/providers/cockroachdb)) | Opt-in, not fail-closed — isolation only applies if a developer sets up and uses the namespace column | Yes | Embeddable library |
| [Fastio](https://fast.io) | Workspace-level isolation, assigned by admin | Audit-logged, but a different category | No (hosted SaaS) | File/workspace storage platform, not a LangGraph checkpointer |
**The gap this fills, stated precisely:** tenant isolation is no longer
scarce — `langgraph-tenancy` provides it as a wrapper, and LangSmith
Deployment and Bedrock AgentCore provide it at the platform layer. What none
of them provide is enforcement *inside* a tenant: per-agent, per-region
control over a swarm's shared memory. That is the gap this project targets,
and it is narrow enough to say so plainly rather than dress up the
tenant-isolation work as novel.
**Where we could be wrong or out of date:** competitive facts move. If
another checkpointer has since gained per-agent memory scoping, or if the
characterizations above are stale, open an issue — this table should stay
accurate, not favorable.
## Development workflow
This project uses Spec-Driven Development. The governing documents are:
- `.specify/memory/constitution.md` — non-negotiable project principles
(isolation guarantees, security requirements, testing standards). Read
this first; it overrides anything else if there's a conflict.
- `specs/001-hyperbus-saver-core/spec.md` — the current feature spec
(problem, user stories, acceptance criteria — no implementation detail).
- `specs/001-hyperbus-saver-core/plan.md` — technical plan (once generated
via `/speckit.plan`).
- `specs/001-hyperbus-saver-core/tasks.md` — task breakdown (once generated
via `/speckit.tasks`).
If you're using an AI coding agent with Spec Kit installed
(`specify init` in this repo), the standard flow from here is:
```
/speckit.clarify # resolve the open questions at the bottom of spec.md
/speckit.plan # generate the technical plan from spec.md + constitution.md
/speckit.tasks # break the plan into implementable tasks
/speckit.analyze # cross-check spec/plan/tasks for consistency
/speckit.implement # execute
```
## See it work
Three runnable examples:
```bash
python examples/01_serialization_benchmark.py # serialization, honestly scoped
python examples/02_isolation_demo.py # tenant isolation
python examples/03_stress_test.py # isolation + capabilities at scale
```
See [`examples/README.md`](examples/README.md) for details on what each one
actually measures and its honest scope limits.
## Quickstart
For LangGraph, use the adapter rather than this package directly:
```python
from hyperbus_core import CapabilityRegistry, Permission
from hyperbus_langgraph import HyperBusSaver
grants = CapabilityRegistry()
grants.grant("support-agent", "customer-support", Permission.READ_WRITE)
graph = builder.compile(
checkpointer=HyperBusSaver(tenant_id="acme-corp", capabilities=grants)
)
graph.invoke(state, {"configurable": {
"thread_id": "conv-1",
"hyperbus_region": "customer-support",
"hyperbus_agent_id": "support-agent",
}})
```
The core engine is also usable directly, for a framework with no adapter yet:
```python
from hyperbus_core import HyperBusEngine, InMemoryBackend
engine = HyperBusEngine(tenant_id="acme-corp", backend=InMemoryBackend())
engine.put("thread-1", "checkpoint-1", {"messages": [...]}, {"step": 1})
record = engine.get("thread-1", "checkpoint-1")
```
With the capability layer enabled, an agent is confined to the regions it was
granted:
```python
from hyperbus_core import CapabilityRegistry, HyperBusEngine, InMemoryBackend, Permission
grants = CapabilityRegistry()
grants.grant("support-agent", "customer-support", Permission.READ_WRITE)
grants.grant("billing-agent", "billing-internal", Permission.READ_WRITE)
engine = HyperBusEngine("acme-corp", InMemoryBackend(), capabilities=grants)
engine.put(
"thread-1", "ckpt-1", {"invoice": 42}, {},
region="billing-internal", agent_id="billing-agent",
)
# The support agent is granted its own region, so this call is authorized --
# and still returns None, because it cannot address the billing region.
engine.get("thread-1", "ckpt-1", region="customer-support", agent_id="support-agent")
# Asking for billing directly is denied outright.
engine.get("thread-1", "ckpt-1", region="billing-internal", agent_id="support-agent")
# raises CapabilityError
grants.revoke_all("support-agent") # one-call kill switch
```
Once a registry is attached, enforcement is unconditional: a call that names
no `agent_id` raises rather than proceeding unchecked, and naming an
`agent_id` on an engine *without* a registry also raises rather than silently
passing. Subgraph state is addressed with `checkpoint_ns=...`.
## License
Apache License 2.0 — see [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).
Copyright TenantSwarm.ai, Inc.
Connection Info
You Might Also Like
Train-in-Silence
The first Task-Aware MCP server and automated VRAM calculator for LLM...
stacklit
108,000 lines of code. 4,000 tokens of index. One command makes any repo...
AppClaw
AI-powered mobile automation agent — describe what you want in plain...
pdf-mcp
Production-ready MCP server for PDF processing with intelligent caching....
kotadb
Local-only code intelligence API for AI developer workflows (Bun +...
gemini-api-docs-mcp
A remote HTTP MCP server for searching Google Gemini API documentation.