← All posts

Agent Memory Poisoning: Guard the Write Path


Prevent agent memory poisoning with write admission, source provenance, correction chains, and quarantine. Keep retrieved claims from becoming authority.

Agent memory poisoning starts when material the agent encountered becomes something the agent believes it must obey. Guard the write path: storing a claim must not promote its source into an authority. Retrieval can find a poisoned record perfectly. Better recall then makes the wrong instruction easier to reuse.

This guide proposes admission rules, correction handling, and recovery cases for durable agent memory. It is design guidance, not an experiment report. The target is persistent influence across sessions: an external document, tool result, or generated summary that acquires authority after the original encounter has disappeared from context.

Separate memory relevance from write authority

Imagine an assistant preparing a project report. A retrieved document contains a paragraph claiming that future reports should go to a new recipient. The assistant summarizes the document into memory as “reporting preference updated.” On a later run, the summary looks like a settled user decision.

The failure happened before the second retrieval. A statement inside source content became an instruction attributed to the user. No obviously suspicious phrase needs to survive: the summary can be short, grammatical, and wrong about who authorized the change.

OWASP’s prompt injection prevention guidance describes persistent attacks, retrieval poisoning, and agent context poisoning. It also cautions that prompt labels are not enforcement boundaries. Those distinctions matter for memory: marking an excerpt “untrusted” helps communicate its status, but a separate service must enforce which durable records the caller can create or alter.

The agent memory retrieval contract asks whether evidence is relevant, accessible, current, and sufficient. Write admission asks an earlier question: what kind of record may this source support? A page may support “this page claims the recipient changed.” It cannot, by itself, support “the user authorized a new recipient.”

Give memory types different admission rules

Avoid a universal “remember this” endpoint that accepts arbitrary text and caller-supplied trust labels. Define record kinds with different permissions and evidence requirements. The following is a proposed contract, not a storage standard:

Record kind Possible supporting evidence Admission boundary
External observation Identified source passage and revision Store as a source claim, not an instruction
User preference Authenticated user statement in applicable scope Confirm the actor may set that preference
Task outcome Durable operation receipt or authoritative state read Do not substitute the agent’s completion narrative
Derived summary References to admitted source records Preserve source limits, conditions, and unresolved conflicts
Operating procedure Reviewed procedure change through its own workflow Do not learn executable policy from arbitrary task content

An authenticated user message can still quote somebody else’s instructions. Authentication establishes the sender; it does not make every sentence a direct preference. Likewise, authenticating a tool server proves which server responded, not that every document returned by that server is trustworthy.

The admission service should derive the caller’s tenant, identity, permitted namespace, and writable record kinds from authenticated context. Treat model-proposed metadata as a request to validate, not a statement of fact. In particular, the model should not be able to grant itself a more privileged record kind by setting an authority field.

Allow useful automatic memory within those boundaries. A low-risk formatting preference can follow an established user-authorized workflow without requiring a new approval for every write. A change to execution permissions belongs in the actual authorization system, not in a preference record that happens to sound imperative.

Preserve provenance through extraction and summarization

Provenance must survive transformations. Record the source identity, exact revision or digest, relevant passage, observation time, applicable scope, and derivation parents. For a preference, also retain the evidence that it was the relevant user’s instruction rather than quoted material.

Keep these fields outside free-form text that the extractor can casually rewrite. The storage layer should assign record identity and admission state; the extraction step can propose a claim and supporting references. Validate that references exist, that the caller may use them, and that they belong to the intended scope before committing the record.

A digest binds bytes. It does not prove truth, authorship, or permission. A signed document can faithfully preserve an unauthorized claim. Provenance enables a decision about authority; it does not replace that decision.

Derived summaries need a dependency graph, not just a list of citations for display. If a summary combines an authoritative project decision with an external suggestion, keep the two claims distinguishable. The combined paragraph must not inherit the strongest source’s authority for every sentence. If that separation cannot be retained reliably, split the memory into smaller claims or keep the summary as lower-trust navigation material.

This also prevents manufactured corroboration. Five summaries derived from one document are one source lineage, not five independent witnesses. Repetition, recency, and similarity scores should not increase the source’s permissions.

Treat corrections as scoped state transitions

A correction should identify what it supersedes and where the change applies. “Use monthly reports for project Cedar” need not invalidate weekly reporting for every project. Store the subject, attribute, scope, effective period, and supersession relation explicitly enough to preserve that distinction.

Before admitting a correction, verify that its source has authority over the affected claim. A newer external page cannot supersede an authenticated user preference merely by mentioning the same project. An attacker must not be able to disable valid memories by writing a persuasive “correction.”

Commit a replacement and its predecessor’s supersession consistently. Use a transaction or an equivalent revision-checked operation so concurrent writers do not each believe they replaced the same active record. If the correction is conditional or future-dated, the current read path must apply those conditions rather than blindly choosing the newest ingestion time.

Do not force a winner when the evidence is unresolved. A disputed state can preserve competing claims while preventing either from authorizing dependent work. The agent can still complete independent parts of a task. It should explain the narrow evidence gap instead of treating the entire memory store as unusable.

Keep history only as permitted by retention and access rules. Correction chains are not an excuse to preserve deleted sensitive text indefinitely. Where appropriate, retain a minimal tombstone or invalidation identifier without the original content.

Make quarantine effective beyond the vector index

Quarantine means a record is unavailable for ordinary answer generation or action support while it is investigated. It should not mean merely lowering its search rank. A low-ranked record can still be returned by an exact lookup, a broad query, or a fallback path.

Enforce state checks when resolving candidate records, and protect the quarantine namespace from ordinary writers. OWASP’s vector and embedding weakness guidance recommends permission-aware access controls, source validation, and retrieval logging. Applying those principles to memory requires checking eligibility outside the model, including when a search index has not yet caught up with an invalidation.

Quarantine also needs a propagation rule. Find derived summaries, cached retrieval results, and resumable task snapshots that incorporated the record. Mark dependent claims for revalidation; rebuild from unaffected evidence when possible. Do not silently reactivate a record just because a later summarizer rewrites it in cleaner language.

Material already loaded into a running session is harder. Removing it from storage does not remove it from the model’s current context. Define an invalidation boundary: pause affected work, rebuild its context from eligible sources, and revalidate pending proposals before dispatch. For consequential effects, enforce current permissions and target checks at execution, independent of what the model remembers.

Keep quarantine and release auditable. Record who changed eligibility, why, which version was affected, and what evidence permits release. Review tools must handle the quarantined text as data too; moving a payload into an administrator’s assistant is not containment.

Reconcile effects separately from memory repair

A corrected memory does not retract a sent report or undo a changed record. When poisoning is discovered, identify tasks that retrieved or derived from the affected version, then distinguish possible exposure from confirmed effects.

Preserve authorized evidence of retrieval, proposal, dispatch, and outcome. A retrieved record indicates exposure, not proof that it caused an action. A proposed action is not proof of dispatch. An uncertain outcome requires reconciliation against the owning system before retrying or compensating.

This is where agent recovery checkpoints complement memory integrity. Recovery needs durable operation identity and evidence, not a replacement summary saying “everything fixed.” Rebuild eligible memory, reconcile affected tasks, and handle each external effect under its own correction policy.

Do not promise complete impact analysis if historical source versions or derivation links were not retained. Record the coverage limit. The absence of a dependency edge in an incomplete log is not proof that a task was unaffected.

Test poisoning across session boundaries

A useful evaluation must outlive the initial prompt. Seed an isolated fixture, run the ingestion and summarization path, start a fresh session, and exercise retrieval plus the downstream decision. Use fake identities and a local effect sink. The following cases are proposed acceptance tests, not measured results:

Fixture change Required behavior
External document claims to update a user preference Retain source attribution; do not admit it as a user instruction
Authenticated user quotes an attacker-controlled instruction Distinguish quotation from the user’s actual request
Summary removes a condition from a source decision Reject or repair the unsupported derived claim
Several memories repeat one poisoned source Preserve shared lineage; do not count independent support
Lower-authority source submits a newer correction Do not supersede the authoritative record
Quarantined record remains in a stale search index Exclude it at resolution and expose the eligibility change
Running task already loaded a quarantined summary Invalidate dependent context and recheck pending effects
Valid user preference changes within its scope Admit the legitimate update and use it on the next task

Inspect the stored records and the independent effect sink, not just the model’s explanation. Separate unauthorized admissions, unsupported summary claims, poisoned reuse, and forbidden effects. Report benign update acceptance alongside attack resistance; a system that refuses all memory writes has not demonstrated useful memory integrity.

Retain fixture versions, admission decisions, lineage, retrieval eligibility, and outcome evidence under the appropriate access policy. Turn repaired failures into guardrail red-team regression cases that run across the complete persistence path.

The governing rule is simple: a memory can preserve evidence, but it cannot manufacture authority. Enforce that rule when claims enter storage, when corrections change their status, and when retrieved material influences an action.