Skip to content

persistence: write cache files owner-only (0700 dir, 0600 file) - #1206

Merged
zzet merged 1 commit into
mainfrom
fix/persistence-cache-perms
Oct 31, 2026
Merged

zzet merged 1 commit into
mainfrom
fix/persistence-cache-perms

Conversation

@zzet

@zzet zzet commented Oct 31, 2026

Copy link
Copy Markdown
Owner

Problem

The daemon's per-repo cache files in internal/persistence — recent queries
(combo.gob.gz), agent-written session notes (notes.gob.gz), memories
(memories.gob.gz), frecency, feedback and keyword caches — were written with
os.MkdirAll(dir, 0o755) and os.Create(path) (default 0644). That is a
world-readable file inside a world-accessible directory. combo stores the
agent's actual recent query strings and notes/memories store free-text the
agent wrote; either can contain sensitive content (query text, pasted keys,
etc.). On a shared machine any local user could read them.

Fix

Add persistDir/persistFile helpers that create directories 0700 and
files 0600 (owner-only) and use them in every Save* (combo, frecency,
notes, memories, feedback, keyword). The flags are otherwise unchanged
(os.O_RDWR|O_CREATE|O_TRUNC), so callers behave identically. Cache data is
now owner-only at rest.

The sqlite sidecar cache (repo-derived indexed graph data, no more sensitive
than the already-world-readable repo) is intentionally left unchanged.

Test

TestPersistCacheModes calls SaveNotes end-to-end and asserts the directory
is 0700 and the cache file is 0600. The persistence suite passes unchanged.

internal/persistence wrote its per-repo cache files with os.MkdirAll(dir, 0o755)
and os.Create(path) — a world-readable 0644 file inside a world-accessible
0755 directory. The caches hold the agent's recent query strings (combo.gob.gz)
and agent-written session notes/memories (notes.gob.gz, memories.gob.gz), which
can contain sensitive content such as query text or pasted keys. On a shared
machine any local user could read them.

Add persistDir/persistFile helpers that create directories 0700 and files 0600
(owner-only) and use them in every Save* (combo, frecency, notes, memories,
feedback, keyword). Flags are otherwise unchanged (os.O_RDWR|O_CREATE|O_TRUNC),
so callers behave identically; the sqlite sidecar cache, which stores
repo-derived indexed graph data no more sensitive than the repo itself, is left
unchanged.
@zzet
zzet force-pushed the fix/persistence-cache-perms branch from ff5bfba to 9aae5dd Compare October 31, 2026 13:54
@zzet
zzet merged commit 4263c6e into main Oct 31, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant