Skip to content

Repository files navigation

Obex

Obex is a memory firewall for AI agents. Agent memory is a writable, privileged input: anything that gets written into it later gets read back as fact, so an attacker who can write to it can change what the agent believes without ever touching a prompt. Obex screens every write by the provenance of the channel it arrived on, so content from an untrusted source is logged and auditable but cannot take a belief.

It is built on nous-state, the open-source belief engine, and on the paper arXiv:2606.22030.

The measured result

A belief established by 4 trusted observations, flooded with 50 false writes from a channel trusted at 0.20, 400 trials per cell, seed 20260709:

memory attack success
last write wins 100.0%
majority vote 100.0%
Obex, provenance capped 0.0%

Attack success is the percentage of attacks where the attacker's false value becomes the agent's belief. Lower is better.

Every number in this repository, in the console, and on the site comes from public/results.json and public/memory_stream.json, which are serialized directly from the benchmarks in nous-state. Nothing is typed in by hand.

Install and run

npm install
npm run dev

Then open http://localhost:3000.

npm run build      # production build, no Python required
npm start

The JSON contracts are committed to public/, so the build has no Python step and no network dependency on the research repository.

Reproducing the numbers

The site renders committed contracts. If you want to regenerate them and check the numbers yourself, you need the research repository, because the builders import both the engine and the benchmark scripts, and the benchmark scripts are research code rather than an installed package.

git clone https://github.com/Pranavsingh431/nous-state
pip install -e ./nous-state

NOUS_STATE_REPO=./nous-state python harness/build_results.py
NOUS_STATE_REPO=./nous-state python harness/build_memory_stream.py
npm run sync

harness/requirements.txt pins the engine as a git dependency, because the taint propagation, trust policy, LangChain firewall and episodic store these builders use are ahead of the current PyPI release of nous-state.

build_results.py carries a drift guard: after building the contract it re-runs each benchmark's own main(), parses the printed tables, and fails loudly if any cell disagrees. The site cannot show a number that has drifted from the benchmark that produced it.

Benchmarks live in nous-state under benchmark/: poison_bench.py, poison_launder_bench.py, mincap_utility_bench.py, taint_engine_bench.py, policy_bench.py, langchain_wrapper_bench.py, episodic_poison_bench.py.

Limitations

These are measured, not hypothetical. Read them before deciding what Obex is worth to you.

The defense has a trust boundary at roughly 0.55. Attack success is 0 percent at every injection volume tested while the attacker's channel is trusted at or below 0.50, measured on the 4 value configuration with 4 trusted observations. The breakpoint is 0.55. Above it the defense degrades, and against an attacker who has fully forged a trusted channel at 0.90 it fails completely, at 100.0 percent attack success. Reliability weighting cannot protect content it wrongly trusts. If your attacker can compromise a channel you rate highly, Obex does not save you.

Taint tracking is scoped to the memory layer. Provenance propagates through derivation chains inside the Obex pipeline, so content that entered on an untrusted channel keeps its origin tier no matter how many trusted intermediaries re-observe it. Measured end to end: routed through a trusted intermediary that forgets the untrusted origin, attack success returns to 100.0 percent; with propagation it is 0.0 percent. This is not general information-flow control. If your code fetches an attacker-controlled page, summarizes it elsewhere, and hands the summary to Obex as first-party input with no chain declared, Obex believes you. Declaring the chain at the boundary is integration work you have to do honestly.

Extraction coverage on free-form text is 12.5 percent. The default rule-based extractor parses narrow phrasings. On structured phrasing it understands 100 percent of writes. On realistic agent chatter it produced claims for 1 of 8 writes. Writes that yield no claims are recorded as unscreened events, counted, and listed in the screening report, never silently passed, because a firewall that screens nothing while you believe you are covered is worse than no firewall. LLM extraction mode handles arbitrary text and is the path to closing that gap. It is nondeterministic and needs an API key, so it is excluded from the seeded benchmarks.

The provenance cap costs benign accuracy at low tiers. A genuinely reliable source routed through a low tier gets discounted along with everything else there. Accuracy falls to 53.8 percent in the reliability conflict regime and 8.8 percent in the stable noise regime when the reliable source sits at tier 0.20. The cap is free at tier 0.50 and above. Tier assignment quality is load bearing for utility, not only for security.

Trust tiers are assigned by an operator, never inferred. There is no learned or automatic trust scoring, and that is a design decision rather than a gap. A content-derived trust signal is the attack surface: the extractor rated a confidently phrased poison at 0.96 reliability, and content-only trust was defeated by a single injection at 100 percent attack success.

Episodic memory results assume a reduced threat model. The episodic numbers model a query-only attacker whose poisoned traces are written by the trusted agent, later retrieved as demonstrations, reduced to the retrieval layer. This is not a MINJA reproduction, and MINJA's published success rates are not comparable to anything measured here.

Layout

app/                Next.js App Router, the console and its routes
components/         UI, charts, the design tokens in app/globals.css
lib/                contract types and the build time loaders
public/             the committed JSON contracts the site renders
harness/            the contract builders, for regeneration only
scripts/sync-data.mjs   copies regenerated contracts into public/, manual

License

MIT. See LICENSE.

About

Memory firewall for AI agents that blocks provenance-based memory poisoning and keeps agent beliefs auditable.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages