TL;DR
- 長期記憶に保存しないもの: 秘匿値、個人情報、権限・承認を変える指示、実行設定。未検証の外部由来情報は出所と失効(TTL)を付けずに置かない。エージェントが自分で導いた要約・推論は、人が確認するまで信頼済みの長期記憶に戻さない。環境識別子は長期記憶が端末外に出るかで決める。
- 理由: 長期記憶は context であって権限ではなく、次のセッションへ指示と情報を持ち越します。完全性と機密性を書き込みの時点で見ます。
- 検査の候補は書き込み前の hook・permissions と、後から回すローカル走査です。auto memory の書き込みに hook が掛かるかは公式に未記載で、既定構成では push protection も届きません(推論)。
- 失効(TTL)と revoke は別です。auto memory は自動では失効しません。漏れた値は削除より revoke が先です。
- 自分たちの memory ストア 59 件では、高確度 secret パターン 0、期限フィールド 0 でした(
社内データ、67e62cec時点)。
はじめに:この記事が答える問い
長期記憶に何を入れないかの結論は TL;DR のとおりです。長期記憶は次のセッションが無条件に読む入力なので、これは便利さではなく境界の問題です。
AIエージェントのOperational Memory設計 は品質、Claude Codeセッション記憶のデザインパターン は効率から扱いました。本記事は攻撃面として見ます。
範囲は防御設計と自分たちの memory ストアの観測で、組織への提言・製品推奨・攻撃手順は書きません。Claude Code の仕様は 2026-10-12〜13 取得の公式ドキュメントと CHANGELOG に基づきます。
1. 長期記憶は「次のセッションへの指示」として読まれる
1-1. context であって権限ではない
公式ドキュメントは、CLAUDE.md と auto memory は会話開始時に読み込まれる強制設定ではない context で、行為を確実に止めるには PreToolUse hook を使う、と書いています(How Claude remembers your project)。起動時には MEMORY.md の先頭 200 行または 25KB の先に達した方まで読み込まれます(公式値)。
2.1.284 では、memory ノートの不可視文字とマークアップを模したタグを Claude に渡す前に無害化する改善が入りました(公式値、CHANGELOG)。ATLAS の AML.M0031 Memory Hardening も、guardrail と区別して永続する agent state を制御する緩和策です(ATLAS データ)。
1-2. prompt injection との境界は「持続するか」
OWASP Top 10 for Agentic Applications 2026 の ASI06 Memory & Context Poisoning は、1 回限りの入力プロンプト(LLM01)を除き、セッションをまたいで伝播する memory の汚染を扱います(別文書 Agentic AI – Threats and Mitigations では T1 で、番号体系が違う)。ATLAS の AML.T0080 も「持続的に」振る舞いを変える手法です(サブテクニック Memory の maturity は Realized)。
持ち越しの実例です。
- ChatGPT: アップロード文書経由の間接 prompt injection で memory に偽の情報や指示が書き込まれた(Rehberger 2024-05)
- ChatGPT macOS アプリ: memory の指示が以後のセッションに持ち越され外部送信が続いた。修正は外部送信の経路で、文書から memory への書き込み自体は残ると著者は書く(Rehberger 2024-09)
- Gemini: アップロード文書経由で、後続の発話をきっかけに long-term memory へ偽の情報が保存された(Rehberger 2025-02)
LLMガードレール設計 の言葉では、長期記憶は次のセッションが無条件に読む取得ドキュメントです。
1-3. 自分たちの memory ストアを「指示の束」として数える
観測したのは Claude Code の既定構成(machine-local な ~/.claude/projects/<project>/memory/)ではなく、別リポジトリで git 管理され、push 先がある memory ストアです。
項目(社内データ、67e62cec 時点) | 値 |
|---|---|
索引 MEMORY.md の行数 | 59 |
| 種別 | feedback 44 / project 15 |
| 規範語(禁止・しない・使わない・触らない・必ず・必須)を含む索引行 | 19 / 59 |
| 承認・merge・許可・権限・auth を含む索引行 | 9 |
件数は正規表現の一致行数で、規範の数ではありません。言えるのは、規範語を含む行が毎セッション冒頭で読まれる、までです。Agentic Misalignment:人間に戻す規約を数えた と同じく、規約があることと強制する検査があることは別です。
1-4. 持ち越しの実例:長期記憶の文脈が追跡ファイルに残っていた
本リポジトリでは、長期記憶から注入された文脈ブロックが、追跡される指示ファイルに 1 件残っていました(無害な定型文。社内データ、ref c0fb8b73)。中身は無害でも、「長期記憶 → 指示ファイル → 以後の全セッション」という経路は成立していました。このブロックは PR #650(2026-10-14)で除去し、main 1861597b の時点で残りは 0 件です(社内データ)。
残っていた理由は 2 つあり、互いに独立していました。1 つは、除去の仕組みが対象をリポジトリ直下の 2 つのパスに固定していて、下の階層にある同名のファイルを見ていなかったことです。任意の階層に広げる修正は #652 で済ませました。もう 1 つは、このマシンの hooksPath が除去の仕組みを置いたディレクトリを指しておらず、hook 自体が起動していなかったことです。hooksPath は 2026-10-14 に有効にしました。前者だけを直しても、後者が残っていれば何も起きません。注入の頻度は分かりません。
2. 何を保存してはいけないか:判断表
2-1. 判断表
| 類型 | 例 | 損なうもの | 扱いと判断条件 | 根拠 |
|---|---|---|---|---|
| 秘匿値 | API キー、アクセストークン、秘密鍵、セッション cookie、接続文字列 | 機密性 | 値は保存しない。値は secret manager 等に置き、memory には参照名(値ではない)だけを書く。参照名に内部ホスト名・アカウント名を含めない | OWASP ASI06 緩和策(commit 前の sensitive content スキャン)、NHI2 / NHI7 と ASI06 の対応付け、GitHub secret scanning |
| 個人情報・規制対象の情報 | 政府 ID 番号、金融口座番号、健康情報 | 機密性 | 値そのものが次のセッションの作業に要るかで決める。要らないなら置かない。要る場合も値ではなく所在を置き、共有・同期範囲が自分の端末を超えるなら所在も置かない | 本記事の整理(claude.ai の memory の公式仕様を例に採った) |
| 環境識別子 | アカウント名、内部ホスト名、組織・リポジトリ名、絶対パス | 機密性(単体の秘匿度は低いが攻撃の足場) | 長期記憶が端末外に出る(別リポジトリへの push、クラウド同期など)なら置かない。端末内に留まるなら、作業に要るものだけ置く | 本記事の整理(一次ソースの禁止規定は無い)、自リポ観測 |
| 権限・承認を変える指示 | 「この操作は確認不要」「この種の変更は自動で merge してよい」 | 完全性 | 書いても強制にならない。許可も禁止も permissions / hook で表す | Claude Code memory ドキュメント、ATLAS AML.M0031 |
| 未検証の外部由来情報 | 取得した Web ページ、アップロード文書、ツール出力から抜いた事実や指示 | 完全性 | 出所(source)と失効(TTL)を付けずには置かない | OWASP ASI06 緩和策(出所の記録、未検証 memory の失効)、第 1 節の実例、MINJA |
| エージェントが自分で導いた要約・推論(未検証) | 外部入力や過去の作業から導いた結論・一般化を、人の確認なしに書いたエントリ | 完全性 | 自動で信頼済みの長期記憶に戻さない。人が確認したものだけを残す。ユーザーの訂正・指示を記録したエントリはこの行に入れない | OWASP ASI06 緩和策(自己生成出力の自動再取り込みの禁止)。訂正・指示の記録との区別は本記事の整理 |
| 実行設定 | hook のコマンド、MCP サーバ定義、permission mode | 完全性 | 長期記憶ではなく設定ファイルに置き、エージェントに書かせない(第 5 節) | Claude Code memory ドキュメント、OWASP の事例表、CVE |
2 行目は、claude.ai の memory が政府 ID 番号や金融口座番号を保存しないという公式仕様(Claude のヘルプ)を例に採った本記事の整理で、auto memory の仕様ではありません。3 行目は一次ソースの無い整理です。
5 行目の MINJA は、攻撃者が memory を直接書き換えず、通常ユーザーとしてクエリするだけで注入する脅威モデルを置いています(arXiv 2503.03704)。
6 行目: auto memory は公式に「ユーザーの訂正や好みに基づいて Claude 自身が書くノート」なので、OWASP の「エージェント自身の生成出力」を文字どおり当てはめるとストア全体が対象になります。訂正・指示の記録を外し、自分で導いた未検証の要約・推論だけを対象にしました。
保存してよいのは、判断の理由、出典 URL、値を含まない再現手順です。
2-2. 完全性と機密性を同じ書き込み境界で見る理由
OWASP ASI06 の緩和策は、memory への書き込みとモデル出力を commit 前に悪性・sensitive の両面でスキャンするよう求めています。NHI 対応表でも NHI2 Secret Leakage と NHI7 Long-Lived Secrets が ASI06 に対応付けられています(理由文は無く、言えるのは対応付けまで)。poisoning 対策だけでは完全性の検査しか載りません。LLM01 / LLM02 の整理は OWASP LLM Top10 AI開発セキュリティ設計2026 に任せます。
2-3. 自分たちの memory ストアでの観測:secret パターンは無いが識別子はある
高確度 secret パターン 12 種に一致したファイルは 0、全履歴の追加行でも 0 行、メールアドレス形式と /Users/ の絶対パスも 0 でした。一方、アカウント名らしき語を含むファイルが 5、組織名・リポジトリ名を含むファイルが 18 ありました(社内データ、67e62cec 時点)。
正規表現で見えない secret(クエリ文字列、値の言い換えなど)があるので、言えるのは「高確度パターン 0 件」までです。端末外に出る構成なので、識別子を含むファイルは見直しの対象で、見直しは済んでいません。
3. 書き込み境界で検査する
3-1. 書き込み経路の観測
本リポジトリの .claude/settings.json には、memory への Write / Edit を対象にした allow / deny / ask ルールが 0 件でした。PreToolUse hook の matcher は Bash だけで、PostToolUse は整形のみです(社内データ、1861597b 時点)。memory への書き込みに事前検査も確認もありません。AIエージェントの権限は影響範囲で設計する で実測した hook の不具合(修正済み、PR #467)の教訓、tool_input の下を読み本番と同じ形の入力で確かめる、を下の擬似 hook に引き継ぎます。
3-2. 書き込み時に置ける検査の候補と、その届く範囲
前提として、auto memory の書き込みが Write / Edit のツール呼び出しを経るかは、memory・hooks・hooks-guide・errors・tools-reference の公式ドキュメントに記載がなく、Edit|Write の matcher は Bash 経由の書き込みには掛かりません(Hooks guide)。
ローカル走査(読み取り専用。件数だけを出す)
# 既定のパス。autoMemoryDirectory などで変えている場合は実パスに置き換える
M=~/.claude/projects/<project>/memory
# 2-3 で使った 12 種のうち 5 種の例
PAT='ghp_[A-Za-z0-9]{20,}|github_pat_|sk-ant-|AKIA[0-9A-Z]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----'
grep -rlE "$PAT" "$M" | wc -l # 高確度パターンに一致したファイル数
grep -c '^- \[' "$M/MEMORY.md" # 索引のエントリ数
# git 管理している場合のみ: 履歴の追加行を数える(+++ のヘッダ行は除く)
git -C "$M" log -p --format= -- . | grep '^+[^+]' | grep -cE "$PAT"
# secret scanner の一例: gitleaks の dir モード(--redact で値をログと標準出力から伏せる)
gitleaks dir --redact --no-banner "$M"
gitleaks の dir は repo 外も走査でき、ディレクトリ走査モードを持つ scanner なら同じ位置に置けます(gitleaks の README は「feature complete」で、今後はセキュリティパッチのみ)。
既定の machine-local な auto memory には push protection / secret scanning は届きません(公式の対象範囲 About push protection からの推論)。git 管理して GitHub に push しているなら push 時に検査されえます(有効化の設定による)。ローカル走査はその手前を埋めます。
PreToolUse hook(擬似例。auto memory の保存経路に効くかは未確認)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-memory-write.sh" }
]
}
]
}
}
#!/bin/sh
# 擬似例(動作は未検証): check-memory-write.sh
PAT='<上の走査と同じパターン>'
input=$(cat)
# tool_input.file_path は書き込み先の絶対パス。照合先は自分の memory ディレクトリの実パスにする
path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
case "$path" in
"$HOME"/.claude/projects/*/memory/*) ;;
*) exit 0 ;;
esac
# 書き込む内容は Write なら content、Edit なら new_string(Edit で content を見ても空)
body=$(printf '%s' "$input" | jq -r '.tool_input.content // .tool_input.new_string // empty')
if printf '%s' "$body" | grep -qE "$PAT"; then
echo "memory への書き込みに secret らしき値があります" >&2
exit 2
fi
構造は hooks-guide の公式例「Block edits to protected files」にそろえました。exit 2 でツール呼び出しはブロックされ、stderr が拒否理由として Claude に渡ります(Hooks reference)。permissionDecision とは混ぜていません。
発火の確かめ方。 防御側の検証として、自分の memory ストアだけで行います。
- テスト用のプロジェクトで、ブロック条件に無害なダミー文字列(例:
HOOK-CHECK-DUMMY-0001)を一時的に加える - Claude に「この文字列を覚えておいて」と依頼する
- 拒否メッセージが返るか、「Saved N memories」の表示とともにダミー文字列が memory ディレクトリに書かれたかを見る
- ダミー条件を外し、テスト用の memory を消す
著者はこの手順をまだ実行しておらず、発火は確かめていません。
permissions の deny ルール(書式は公式で確認・動作は未検証)
{
"permissions": {
"deny": ["Edit(~/.claude/projects/*/memory/**)"]
}
}
user settings に置く例です。公式によれば、ファイル権限は Edit(path) / Read(path) でのみ判定され Write(path) は参照されません。deny は組み込みのファイルツールと、Claude Code が認識する Bash のファイルコマンド(tee など)・リダイレクト先に適用され、自分でファイルを開く Python / Node には適用されません(Permissions)。deny は auto memory の保存も止めうる強い設定で、permissions.ask なら確認を挟む形になります(いずれも動作は未検証)。
3-3. 検査で拾えないもの
MINJA の著者は、プロンプトレベルの検知が一部の設定ではほとんどの注入を検出し、別の設定では 1 件も検出しなかったと報告しています。検査だけでは閉じないので、出所の記録と失効(第 4 節)を組み合わせます。
4. 失効(TTL)と revoke を分ける
本節の失効(TTL)は「露出していてよい期間」で、前掲記事の expiry(再検証の期限)とは別です。
4-1. 自動では失効しない
memory ファイルは transcript を消す cleanupPeriodDays の対象外で、ユーザーか Claude が編集・削除するまで残ります(公式値、2026-10-12 確認)。OWASP は機微度に応じた保持期間の最小化と、未検証 memory の失効を緩和策に挙げています。
自分たちの memory ストアで期限を書式で持つエントリは 0 / 59 でした。modified を持つファイルは 31 ありますが、最終更新日で期限ではありません(社内データ、67e62cec 時点)。
4-2. 「消す」は 3 つある
| 操作 | 何が消えるか | 何が残るか | 根拠 |
|---|---|---|---|
| 索引から外す | 起動時に MEMORY.md 経由で読み込まれる経路 | トピックファイル本体。残る限り、必要時にオンデマンドで読まれうる | Claude Code memory ドキュメント |
| ファイルを削除する | 作業ツリー上の内容 | memory ディレクトリを git で管理していれば履歴 | 自リポ観測(削除済み 2 ファイルが履歴に残る。社内データ、67e62cec 時点) |
| 値を revoke / rotate する | 漏れた値の効力 | 値の文字列(効力は無い) | GitHub secret scanning |
GitHub は、Git 履歴からの除去は時間がかかり、credential を revoke 済みなら多くの場合不要だと書いています(About secret scanning)。まず revoke / rotate し、履歴の掃除は必要ならその後です。検知後の rotate は GitHub MCPでsecret scanning で扱っています。履歴に残る削除済みファイル 2 件(67e62cec 時点)の中身は読んでいません。
5. 長期記憶と実行設定の線引き
線は「強制されるか」で引きます。公式は CLAUDE.md と auto memory を「context, not enforced configuration」とし、.claude/rules/ も CLAUDE.md の仕組みの一部です(強制されないことは CLAUDE.md の公式記述からの推論)。OWASP の事例表では、Cursor の設定ファイル系の事例が ASI06 ではなく ASI04 / ASI05 に、Rules File Backdoor 系が ASI04 / ASI08 / ASI09 に分類されています。本記事はこれにならい、実行設定を長期記憶(ASI06)とは別の箱として扱います(本記事の対応付け)。
| 置き場所 | 誰が書けるか | 効き方 | 本記事の対応付け | 扱い |
|---|---|---|---|---|
| auto memory | Claude(ユーザーも編集できる) | context(強制しない) | ASI06 の範囲 | 第 2〜4 節の判断表と書き込み検査 |
CLAUDE.md / .claude/rules/ | ユーザー。project のものは repo・fork 経由で他人も書ける | context(強制しない) | context の側。ASI 番号は付けない | 禁止を書いても強制にならない。止めたい行為は permissions / hook に移す |
| settings.json の permissions / hooks | repo にコミットされれば他人も書ける | 実行設定(強制する) | ASI06 とは別の箱 | エージェントに書かせない。変更は人がレビューする |
| MCP サーバ設定 | 同上 | 実行設定(ツールの追加・差し替え) | 同上 | 変更時に再承認する |
他人が書ける context は供給経路の問題で、Pillar Security は、ルールファイルを実行コードと同等にレビューするよう書いています。
実行設定の側の事例です(いずれも修正済み)。
- CVE-2025-53773: 研究者の原典によれば、ワークスペース設定の書き換えで自動承認が有効になり持続した(CVE レコードの記述ではない)
- CVE-2025-54136: Cursor で、承認済みの MCP 設定が変更されても再承認を求めなかった
- CVE-2026-33068: Claude Code が、repo にコミットされた
.claude/settings.jsonの permission mode をワークスペース信頼の判定より前に読んでいた - CVE-2026-40068: Claude Code で、worktree の検証不備により信頼ダイアログを飛ばして
.claude/settings.jsonの hooks が実行されえた
project の settings の autoMemoryDirectory には hooks と同じワークスペース信頼のルールが掛かり、memory の置き場所自体が実行設定の側にあります。止めたい行為は実行設定で止め、それをエージェントに書かせない。判断表の最終行はこの理由です。
6. この観測と整理の限界
- サンプルは別リポジトリで git 管理された 1 ストア(59 件、
67e62cec時点)で、一般化しません - secret の 0 件は正規表現の範囲で、「無い」の証明ではありません
- 「個人情報」「環境識別子」の行と「自分で導いた要約・推論」の切り分けは本記事の整理です
- 擬似 hook・deny は未検証です(deny は書式のみ公式で確認)。1-4 は 1 リポジトリ・1 台のマシンでの 1 件の事実です
- ChatGPT の memory の仕様は一次ソースを取得できず扱いません
まとめ
手元で次の順に確かめられます。
- 自分の memory ディレクトリを読み取り専用で走査し、件数だけを出す(3-2 のコマンド)
- 判断表の 7 類型で既存エントリを振り分け、秘匿値・権限を変える指示を外す
- 承認や禁止は permissions / hook に移し、hook の発火はダミー文字列で確かめる
- 外部由来・未検証のエントリに出所と失効(TTL)を付ける
- 漏れた値は削除より先に revoke する
権限を影響範囲から見直すなら AIエージェントの権限は影響範囲で設計する を参照してください。
FAQ
MEMORY.md に API キーを書いてしまいました。ファイルを消せば十分ですか
十分ではありません。先に値を revoke / rotate します。memory ディレクトリを git で管理していれば、ファイルを消しても履歴に残ります。GitHub は、credential を revoke 済みなら履歴からの除去は多くの場合不要だと書いています。履歴の掃除は revoke の後で、必要なら行います。
prompt injection 対策をしていれば memory poisoning も防げますか
扱う境界が違います。OWASP ASI06 は 1 回限りの入力プロンプト(LLM01 の範囲)を除き、セッションをまたいで持続する memory の汚染を扱います。MITRE ATLAS も、対話中のコンテンツを評価する guardrail と、永続する agent state を守る Memory Hardening を別の緩和策として定義しています。
CLAUDE.md や memory に「この操作は確認不要」と書けば承認の代わりになりますか
なりません。Claude Code の公式ドキュメントは、CLAUDE.md と auto memory を強制設定ではなく context として扱うと書き、Claude の判断に関わらず止めたい行為には PreToolUse hook を挙げています。許可も禁止も permissions か hook で表します。
アカウント名やリポジトリ名も保存してはいけませんか
一次ソースの禁止規定は無いので、本記事の整理として答えます。秘匿値ではありませんが、攻撃の足場になる環境識別子です。長期記憶が端末外に出るかで決めます。自分たちの memory ストアは git 管理で端末外に出る構成で、高確度 secret パターンは 0 件でしたが、識別子を含むファイルは複数ありました。
References
- OWASP, Top 10 for Agentic Applications for 2026(ASI06、NHI 対応表、事例表。確認日 2026-10-12)
- OWASP, Agentic AI – Threats and Mitigations(T1 Memory Poisoning。確認日 2026-10-12)
- OWASP, LLM02:2025 Sensitive Information Disclosure(確認日 2026-10-12)
- MITRE ATLAS, ATLAS-2026.09.yaml(AML.T0080 / AML.M0031。確認日 2026-10-12)
- Claude Code Docs, How Claude remembers your project(確認日 2026-10-13)
- Claude Code Docs, Hooks reference / Hooks guide(確認日 2026-10-13)
- Claude Code Docs, Permissions(確認日 2026-10-13)
- Anthropic, Claude Code CHANGELOG(2.1.284。確認日 2026-10-13)
- Claude Help Center, Claude の memory(claude.ai の memory。確認日 2026-10-12)
- GitHub Docs, About push protection(確認日 2026-10-12)
- GitHub Docs, About secret scanning(確認日 2026-10-12)
- gitleaks(secret scanner の一例。確認日 2026-10-13)
- Johann Rehberger, ChatGPT: Hacking Memories with Prompt Injection / SpAIware / Hacking Gemini's Memory(確認日 2026-10-12)
- Pillar Security, Rules File Backdoor(確認日 2026-10-12)
- CVE レコード: CVE-2025-53773 / CVE-2025-54136 / CVE-2026-33068 / CVE-2026-40068(確認日 2026-10-13)
- Dong ほか, Memory Injection Attacks on LLM Agents via Query-Only Interaction(MINJA)(脅威モデルの説明にのみ使用。確認日 2026-10-12)
