Signed state: every checkpoint is an attack surface
LangGraph's SQLite checkpointer shipped a SQL injection CVE in March. Memory poisoning hit 95% success in production. The agent's checkpoint store is the next security boundary — and right now it's the most porous one in the stack.
There is a pattern in the 2026 agent stack that almost everyone has bought into and almost nobody has secured.
Memory is now a first-class architectural component. Mem0 covers 21 frameworks. LangGraph writes a checkpoint at every node. Cloudflare ships Agent Memory as a managed service with five retrieval channels. Letta exposes three memory tiers the agent manipulates by hand. The production pattern is three layers — Redis-hot, vector-mid, SQL-cold — and everyone agrees that's how you survive long runs.
The pattern is sound. The thing nobody is talking about is that every one of those memory layers is unsigned, unauthenticated, and writeable from anywhere with credentials to the database.
We are about to spend a year recreating every 1995-era web-session-fixation bug, but with the model's beliefs as the corruptible state. The fix is going to look a lot like what the database community already shipped: transactional integrity, but for what the agent remembers.
What a checkpoint is, and what it isn't
LangGraph's checkpointing is the canonical reference. The runtime writes a checkpoint at every super-step keyed by thread_id. If a worker crashes, the run's lease releases and another worker resumes from the latest checkpoint. The pattern is good. The pattern is also why this matters.
A checkpoint contains: the agent's state, conversation history, reasoning so far, tool-call results, and a pointer to where the next step begins. It is the agent's mind, frozen, on disk.
In LangGraph the canonical production saver is PostgresSaver. The default development saver is InMemorySaver. There is also SqliteSaver, which shipped a SQL injection bug — CVE-2025-67644, CVSS 7.3 — that lets an attacker manipulate SQL queries through metadata filter keys and run arbitrary SQL against the persisted state. The patch is langgraph-checkpoint-sqlite 3.0.1. The disclosure was in March.
That CVE is not a freak accident. It is the first one in a class.
Memory poisoning is the new SQL injection. The store is a database, the agent is the client, and right now the client is trusting every row it reads. Until checkpoint state is signed by the runtime that wrote it, every long-running agent in production is one prompt-injection away from believing whatever the attacker wrote into the row.
The proof-of-concept exploits
This is not theoretical. Two production-relevant attack chains landed in 2026.
Unit 42 at Palo Alto Networks demonstrated a working PoC against Amazon Bedrock Agents. A web page primed with an indirect-prompt-injection payload was visited by the agent. The agent's session-summary process wrote the attacker's instructions into the long-term memory store. The next session — same user, different question — read the poisoned summary, and the chatbot silently exfiltrated the user's conversation history to a remote C2 server using the web-access tool.
The MINJA paper showed over 95% injection success rates against production agents using a similar pattern.
Google researchers reported a 32% increase in malicious prompt-injection payloads embedded in web content between November 2025 and February 2026. The category is growing because it works.
Every one of these attacks shares the same shape. The memory write path runs without trust. The memory read path trusts everything. The model becomes the attacker's proxy.
Why this is a runtime problem, not a model problem
The reflex is to ask the model to be smarter — detect prompt injection, refuse poisoned context, prefer trusted sources. That has not worked for two years. It will not start working now.
The right layer to defend is the same layer Prix already defends for filesystem, network, and shell: the runtime, beneath the model, at the boundary where syscalls cross.
A signed-state contract looks like this. Every checkpoint the runtime writes is signed by the runtime's keypair. Every checkpoint the runtime reads is verified before it is given to the agent. The agent never reads raw rows. The agent reads what the verifier promises was written by a legitimate previous step of the same workflow.
# Checkpoint envelope
checkpoint_v2:
thread_id: "user-alice-research-task-7c4f"
step: 14
state: <opaque agent state blob>
parent_hash: <hash of step 13's envelope>
written_by: [email protected]
written_at: 1747000000
signature: <Ed25519 over (thread_id, step, state, parent_hash, written_by, written_at)>
The signature binds the row to the writer. The parent_hash makes the chain tamper-evident — change step 8 and step 14's verification fails. The runtime refuses to load any checkpoint whose signature does not verify against the keypair tied to the agent's signed container.
This is not exotic. It is the Prix container signing model extended one architectural layer down. We already sign the manifest at publish. We sign the encrypted payload. We refuse to load unsigned containers. The next surface to sign is the state the runtime writes between invocations.
What the long-running pattern actually needs
The Microsoft DELEGATE-52 paper is the other half of this story. Frontier models corrupt 25% of document content over 20 hand-offs without an attacker. With an attacker writing into the memory store, the floor is wherever the attacker wants it.
The teams shipping working long-running agents in 2026 have figured out that durable state plus consolidation is the answer. Anthropic's Dreaming, shipped at Code with Claude on May 6, runs a scheduled between-session process that reads recent sessions, pulls patterns out, writes them to the memory store for the next session. Harvey reported 6x task completion improvement. Wisedocs cut document review 50%.
This works. It also massively amplifies the impact of a single poisoned write. If Dreaming consolidates a poisoned message from session 14 into the persistent memory, every future session reads it. The blast radius of a single successful injection is no longer one conversation — it is every conversation the agent has after.
That is exactly why the signed-state contract has to extend to what Dreaming writes. Every consolidated memory entry signed by the runtime, with a parent_hash chain back to the session it was distilled from, refusable by the verifier when the chain breaks.
The 1990s pattern
If you have been writing databases for any length of time, this should be familiar. The lesson the database community learned the hard way between 1995 and 2005 was: don't trust the store, sign the transaction. Replication didn't get safe until log entries had checksums. Distributed databases didn't get safe until quorum writes had cryptographic commit certificates. Backup integrity didn't matter until backups got signed.
Agent memory is going through the same maturation, compressed into one year. The first ten checkpoint stores were unsigned and trusted. The eleventh got a CVE. The next ten will be unsigned and trusted. The 21st will get a worse CVE.
Or the people building agent runtimes can read the database literature, skip the next decade of incidents, and ship the signed-state contract first.
What to do this quarter
If you are running agents that persist state across invocations:
- Audit what is signed and what is not. Most production stacks sign the container, sign the request, and store everything in between in plaintext. Inventory which writes are signed; the unsigned ones are your attack surface.
- Treat your checkpoint store like a database backup. Backups get signed. Checkpoints should too. If you cannot prove the runtime wrote the row, do not give it to the model.
- Make consolidation processes themselves signed actors. If Dreaming or a similar between-session process writes into long-term memory, that writer needs its own keypair and signature. A single compromised consolidator otherwise pollutes every future session.
The next big incident in agent infrastructure is not going to be a prompt injection. It is going to be a memory store breach, with a clean SQL injection or a hijacked consolidation worker, and an agent that wakes up the next morning believing a thing the attacker wrote into Redis last night.
The boundary is the manifest. The next boundary is the state. Sign it.