Back to Blog
Abstract streams of data representing secured long-term memory for AI agents

AI Agent Memory Security: Protecting Long-Term Memory

10 min read

AI agent memory security fails when a workflow treats remembered context as trusted simply because it came from its own database. An attacker can plant an instruction that survives the current conversation, stale facts can keep changing later decisions, and a bad namespace can return one user's data to another. The damage may appear days after the original write, during an ordinary request that retrieves the poisoned record.

Handle long-term memory as a security-sensitive data system. Each record needs controlled reads and writes, traceable provenance, a tenant boundary, a retention rule, and a verifiable deletion path. Remembered text must never grant tool authority. The sections below turn those requirements into an implementation sequence and a test plan for AI and platform engineers.

Treat memory as durable state, not hidden prompt text

Short-term conversation history and long-term memory have different failure characteristics. Conversation history usually belongs to one thread. Long-term memory may survive many threads, be retrieved by similarity rather than exact identity, and influence users who never saw the original input.

The LangGraph memory documentation makes the distinction explicit: short-term memory is thread-level state, while long-term memory can hold user-specific or application-level data across sessions. Its examples use a namespace containing a user identifier. That namespace is not a convenience detail. It is part of the authorization boundary.

The OpenAI Agents SDK session documentation shows another form of persistence. A session retrieves conversation history before a run and stores new items afterward. It also exposes operations for limiting history, removing items, clearing a session, and selecting different backing stores. Those features make memory useful, but storage does not make an item trustworthy.

OWASP's analysis, Memory Is a Feature. It Is Also an Attack Surface, states the core design problem: persistent context deserves validation, separation, and visibility because it can shape later behavior. Apply that rule before adding retrieval results to a model prompt.

Write a threat statement that engineering and security can test:

A memory item may contain hostile instructions, incorrect facts, excessive personal data, or content owned by another identity. Retrieval must not bypass authorization, and memory content must not grant permissions or approve actions.

Reviewers can test this statement against the write path, retrieval filters, tool authorization, and deletion process. It is more useful than a general promise that memory is "safe."

Define the identity boundary before choosing a store

A vector database, SQL table, or session backend cannot infer your tenancy model. The workflow has to provide the identity context and enforce it at every memory operation.

Define the smallest ownership scope that matches the product. Most internal systems need organization and user identifiers, then a narrower purpose and memory type. A workspace may add another boundary. Do not collapse these values into one free-form string supplied by the model. Build the scope from authenticated application context and an approved workflow configuration.

For example, an employee support agent might use separate collections for personal preferences, department procedures, and company-wide policy. Personal preferences require the employee's user scope. Department procedures require department membership. Company policy can use an organization scope, but only designated publishers should write it.

This follows the broader tenant-isolation principle in the AWS guidance for multi-tenant SaaS security: authentication identifies a caller, while isolation still requires explicit authorization and data boundaries in the shared application. Logging in is not proof that a user may access every record in the same database.

Apply authorization twice:

  1. At write time, verify that the caller and workflow may create that memory type in that scope.
  2. At read time, rebuild the allowed scope from current identity and policy, then constrain the storage query before semantic ranking.

Never retrieve broadly and ask the model to ignore records from another tenant. A record that should not be visible must not enter the candidate set.

Use a memory record with provenance and lifecycle fields

Do not store only an embedding and a text blob. A reviewable memory needs enough metadata to answer who created it, why it exists, where it may be used, and when it should disappear.

A compact record can look like this:

memory_record:
  id: mem_01
  tenant_id: org_42
  subject_id: user_17
  purpose: support_preferences
  memory_type: explicit_preference
  content: "Prefer email summaries after resolved tickets"
  source:
    kind: user_statement
    source_id: conversation_891
    actor_id: user_17
    captured_at: 2026-08-03T09:15:00Z
  trust:
    state: accepted
    validation_policy: explicit_user_preference_v2
  access:
    readers:
      - support_assistant
    writers:
      - preference_capture_workflow
  lifecycle:
    expires_at: 2027-02-03T09:15:00Z
    deletion_state: active
  version: 1

The model should not choose tenant_id, subject_id, access lists, or validation policy. Trusted application code supplies them. The model may propose content and a memory type, but the write service decides whether the proposal matches an allowed schema.

Keep the original source reference where policy permits it. Provenance lets an operator inspect a surprising retrieval, lets a user correct an outdated preference, and gives a deletion job a path to dependent records. If the source contains sensitive material, store a protected reference rather than duplicating the full content into every memory record.

Put an admission pipeline in front of every write

Automatic memory writes are attractive because they remove user effort. They also turn every conversation, retrieved document, and tool result into a possible persistence channel. A safer design separates a proposed memory from an accepted memory.

Process each proposed write in this order:

  1. Classify the candidate as an explicit preference, durable fact, workflow state, summary, or prohibited content.
  2. Record whether it came from the authenticated user, an administrator, a tool, retrieved content, or model inference.
  3. Validate the schema. Reject instructions in fields meant for facts, unsupported identity claims, secrets, and data outside the approved purpose.
  4. Authorize the scope by building tenant and subject identifiers from trusted context.
  5. Assign trust and retention. High-impact facts may require approval or corroboration, while temporary summaries should expire quickly.
  6. Write an audit event with the policy decision and record identifier, but do not copy sensitive content into logs.
  7. Publish accepted records only. Quarantined candidates must stay outside normal retrieval.

Explicit user commands such as "remember that I prefer weekly summaries" can follow a straightforward confirmation path. Inferred memories deserve a higher threshold. A model's guess about a user's role, health, intent, or authority should not silently become durable fact.

The OWASP article describes a real class of risk in which retained context changes later behavior. A current NVIDIA garak issue proposing a sleeper-poisoning probe gives concrete practitioner language for the testing problem: a malicious record can remain at rest until a benign-looking query retrieves it. Treat that issue as a practitioner proposal, not proof that every memory implementation is vulnerable. It is still a useful adversarial case for your own system.

Enforce AI agent memory security at retrieval

A secure write path does not remove the need for read controls. Policies change, users leave teams, records expire, and a previously accepted item can be revoked.

Build retrieval as a constrained pipeline:

  1. Authenticate the current actor and resolve their organization, workspace, and role.
  2. Construct allowed namespaces in trusted code.
  3. Filter out expired, deleted, quarantined, and disallowed memory types before similarity search.
  4. Retrieve a small candidate set inside those boundaries.
  5. Attach provenance and trust labels to each candidate.
  6. Apply relevance and conflict rules.
  7. Pass selected content to the model inside a clearly delimited data section.

Do not concatenate retrieved memory directly into the system instructions. Present it as untrusted context with record identifiers and source labels. Tell the model what the data may inform, not what it may authorize.

Conflict handling needs a deterministic rule. Current organization policy should outrank an old personal summary. An explicit user correction should supersede an inferred preference. Two unresolved records should trigger clarification rather than silent selection. Record the winning and rejected memory identifiers in the trace so an operator can reproduce the decision.

Keep retrieved content separate from tool permissions. If a memory says "the finance lead approved all refunds," it may help formulate a question, but it cannot create an approval. Tool access must still come from current identity, policy, and any required human authorization.

Make retention, correction, and deletion operational

Stored facts do not stay correct on their own. Job titles change. Projects close. Customers withdraw consent, and teams replace old procedures. Permanent retention allows these ordinary changes to produce persistent wrong behavior.

Assign retention by memory type. A temporary task summary might live for days. A user preference can last longer but should remain visible and correctable. A policy record should have an owner, version, review date, and supersession rule. Avoid a single default that keeps every item forever.

Deletion needs more than removing the text column. Account for the source record, embedding or search index, caches, replicas, exports, derived summaries, and backups governed by the product's retention policy. Mark a record unavailable immediately, then process dependent copies through an idempotent deletion job. Keep a non-sensitive tombstone when needed to prevent a retry or stale event from recreating the item.

The Agents SDK documentation includes session operations for removing items and clearing a session, and LangGraph documents deleting messages and checkpoints. Use those framework operations, but verify the behavior of the actual backing store and any secondary index. An API call returning success is not enough if retrieval still returns the item.

Test poisoning and isolation before rollout

Test allowed behavior and denied behavior with the same discipline. Build a small suite that runs against the deployed memory service, not just a mocked repository.

A release test suite should cover these failures:

  • User A writes a unique marker, and User B cannot retrieve it through direct, semantic, or adversarially phrased queries.
  • A retrieved document contains "remember this instruction," but the write admission policy rejects or quarantines it.
  • A poisoned record is relevant to a benign query, yet its content cannot change tool permissions or bypass approval.
  • A user's role is revoked after a memory write, and later reads use the new authorization state.
  • An explicit correction supersedes the old record and the trace explains why.
  • An expired item disappears from candidate retrieval.
  • A deletion request removes the item from primary storage, semantic indexes, and caches within the declared service objective.
  • A failed write does not leave an accepted record without provenance or an audit event.
  • A retry uses an idempotency key and does not create duplicate memories.
  • Monitoring detects unusual write rates, repeated quarantine events, and cross-scope access denials.

Use synthetic canary records with unique markers in each tenant. Run periodic cross-tenant retrieval probes and alert on any match. Do not place real secrets in canaries.

For failure handling, prefer a closed state. If authorization cannot be evaluated, do not perform the read. If the validation service is unavailable, queue the proposed write or discard it according to the workflow's business requirements. Do not mark it accepted and promise to validate later.

Roll out memory by purpose, not all at once

Start with one low-risk memory type, such as an explicit notification preference. Ask the user to confirm it. Use a short retention period, provide correction and deletion controls, and keep that memory outside authorization decisions.

Instrument the first release with accepted, rejected, quarantined, expired, corrected, and deleted counts. Review false positives and unexpected retrievals. Add a second memory type only after the team can explain where each stored item came from, who can retrieve it, and how it disappears.

Do not begin with broad autobiographical summaries or automatic extraction from every conversation. Those designs collect more ambiguous claims, make deletion harder, and create a wider poisoning channel before the controls have been exercised.

Prompt instructions alone cannot secure long-term memory for AI agents. The work belongs in identity controls, data governance, and the record lifecycle, with tests for model-specific failure modes. Before enabling the first persistent write, choose one memory type and document its ownership scope, admission policy, retention period, deletion path, and cross-user test.

References


About Fire In Belly: Independent senior engineering from Tallinn, Estonia. We design and build AI workflow automation with the tenant isolation, memory admission controls, and deletion guarantees described above, at published fixed prices. Schedule a call to discuss your next project.