
Hermes Agent 0.20.4 punya bug batas privasi yang perlu diperhatikan oleh pengguna cron. Scheduled job dibuat dengan skip_memory=True dan tool memory masuk denylist, tetapi isi MEMORY.md dan USER.md masih bisa dimuat ke system prompt job tersebut.
Bug ini dilaporkan pada 21 Agustus 2026 melalui issue #91269 dan diberi label P1 oleh upstream. Fix sudah diajukan lewat PR #91270. Saat audit ini dilakukan, seluruh required checks PR sudah lulus, tetapi patch belum merged dan belum masuk release bertag.
Dampaknya perlu dibaca dengan tepat. Ini bukan berarti setiap cron otomatis mengirim file memory ke publik. Namun model yang menjalankan job dapat menerima isi memory di konteksnya. Jika output cron dikirim ke Telegram, Discord, email, webhook, atau tujuan lain, catatan yang seharusnya tidak tersedia untuk job itu berpotensi ikut memengaruhi atau muncul dalam hasil delivery.
Untuk instalasi yang menyimpan identitas, preferensi, detail operasional, atau catatan internal di memory, ini cukup material untuk menahan rollout dan mengaudit job aktif.
Kontrak yang seharusnya berlaku
Hermes punya alasan kuat untuk memisahkan cron dari memory percakapan utama. Cron berjalan non-interaktif, dapat memakai auto-approval, dan sering mengirim hasil ke channel tanpa review manusia sebelum delivery.
Pada source 0.20.4, scheduler sudah memasang beberapa pembatas:
- agent cron dibuat dengan
skip_memory=True; - toolset
memorymasuk daftar yang selalu dinonaktifkan; - background review untuk memory dan skill juga dimatikan;
- tool interaktif seperti messaging dan clarify dibatasi di konteks cron.
Komentar source bahkan menyebut cron system prompt tidak boleh mencemari representasi user. Dari kontrak tersebut, ekspektasi operator cukup jelas: job terjadwal tidak membaca memory lokal dan tidak mendapat tool untuk menulis memory.
Masalahnya, implementasi berhenti satu langkah terlalu awal. Tool memory memang tidak tersedia untuk dipanggil model, tetapi file-backed memory store tetap dapat dibuat saat agent diinisialisasi.
Root cause: memory dinonaktifkan sebagai tool, tetapi tetap dianggap diminta
Alur bug ini melibatkan tiga bagian source.
Pertama, cron/scheduler.py memanggil agent dengan skip_memory=True dan memasukkan memory ke disabled_toolsets. Itu benar.
Kedua, resolver toolset cron tetap dapat mengembalikan memory di enabled_toolsets. Pada instalasi default, toolset platform cron berasal dari konfigurasi tool Hermes. Karena memory masih disebut di daftar enabled, agent menerima kondisi yang kontradiktif: memory aktif di satu daftar dan diblokir di daftar lain.
Ketiga, agent/agent_init.py hanya memeriksa apakah string memory ada di enabled_toolsets:
_memory_toolset_requested = "memory" in (agent.enabled_toolsets or [])
if not skip_memory or _memory_toolset_requested:
# create MemoryStore and load files from disk
Pemeriksaan itu tidak melihat disabled_toolsets. Akibatnya, skip_memory=True dapat dikalahkan hanya karena memory masih tercantum di daftar enabled, meskipun tool yang sama sudah ditolak oleh policy cron.
Setelah MemoryStore dibuat, Hermes memanggil load_from_disk(). Di tahap penyusunan system prompt, agent/system_prompt.py menambahkan blok memory dan user profile jika fitur tersebut aktif. Konfigurasi default 0.20.4 mengaktifkan keduanya:
memory:
memory_enabled: true
user_profile_enabled: true
Hasil akhirnya janggal: model tidak bisa memanggil tool memory, tetapi sudah menerima isi memory sebelum turn dimulai.
Kenapa ini bukan sekadar bug konfigurasi
Operator mungkin mengira denylist cukup untuk menutup akses. Dalam kasus ini, tidak.
disabled_toolsets bekerja pada schema tool yang diberikan kepada model. Ia mencegah model memanggil operasi memory. Namun injeksi MEMORY.md dan USER.md terjadi melalui jalur system prompt, bukan melalui tool call. Karena jalurnya berbeda, menyembunyikan tool tidak otomatis mencegah file dibaca saat startup agent.
skip_memory=True juga belum menjadi jaminan penuh pada 0.20.4. Flag tersebut mencegah external memory provider dibuat, tetapi built-in file store masih boleh hidup jika agent menganggap toolset memory diminta. Celah logika itulah yang terkena oleh bentuk konfigurasi cron default.
Jadi masalah ini bukan karena user sengaja mengaktifkan memory pada satu job. Reproduksi upstream memakai cron normal tanpa menambahkan kebutuhan memory khusus.
Dampak privasi dan operasi
Severity P1 masuk akal karena cron sering punya jalur delivery otomatis. Risiko riil bergantung pada isi memory, prompt job, model, dan tujuan kirim.
Beberapa skenario yang perlu diperiksa:
- cron monitoring server menerima catatan bisnis atau identitas yang tidak relevan;
- daily summary dikirim ke grup dengan audiens lebih luas daripada pemilik memory;
- job webhook menghasilkan payload yang dipengaruhi catatan user profile;
- scheduled report memakai token lebih banyak karena system prompt membawa konteks yang tidak dibutuhkan;
- prompt injection dari sumber eksternal mencoba meminta model mengulang instruksi atau data yang ada di konteks.
Tidak semua run akan membocorkan teks memory. Model dapat menerima informasi tanpa menyalinnya ke output. Namun privacy boundary yang diharapkan sudah gagal saat data tersebut masuk ke konteks job yang seharusnya tidak membacanya.
Ada satu batas penting: audit ini tidak menemukan GitHub Security Advisory atau CVE resmi untuk kasus tersebut. Status upstream saat ini adalah bug P1 dengan risiko session-state dan memory. Sebutannya perlu presisi agar operator tidak meremehkan masalah, tetapi juga tidak mengubah issue menjadi klaim insiden keamanan yang belum dibuktikan.
Fix yang diajukan upstream
PR #91270 memperbaiki masalah di dua lapisan.
Pada agent_init.py, memory baru dianggap benar-benar diminta jika ada di enabled_toolsets dan tidak ada di disabled_toolsets:
_memory_toolset_requested = (
"memory" in _enabled_toolsets
and "memory" not in _disabled_toolsets
)
Pada scheduler, resolver cron juga menghapus memory dari daftar enabled. Ini menghilangkan kondisi kontradiktif sejak awal, bukan hanya mengandalkan guard di agent init.
Test baru membuat MEMORY.md dan USER.md dummy, lalu membangun agent dengan bentuk yang sama seperti cron: skip_memory=True, memory ada di enabled dan disabled. Acceptance criteria-nya tegas:
_memory_storeharusNone;- external memory manager tidak aktif;
- isi kedua file tidak boleh muncul di system prompt;
- flush agent yang memang meminta memory tanpa denylist harus tetap bekerja.
Saat audit ini dilakukan, PR berstatus open dan mergeable. Seluruh required CI checks sudah lulus, termasuk Python test slices, e2e, lint, macOS, Windows, OSV, supply-chain scan, dan Nix. Itu sinyal baik untuk kualitas patch, tetapi belum sama dengan release resmi. Pengguna stable 0.20.4 belum otomatis mendapat perbaikan.
Mitigasi aman sebelum release fix tersedia
1. Audit cron yang punya delivery eksternal
Prioritaskan job yang mengirim hasil ke grup, email bersama, webhook pihak ketiga, atau channel client. Catat target, prompt, profile yang dipakai, dan apakah output bisa dibaca orang selain pemilik instalasi.
Jika job tidak mendesak, pause sampai patch hadir dalam release bertag. Ini pilihan paling aman untuk job dengan audiens luas.
2. Jangan mengandalkan denylist memory saja
Menambahkan memory ke agent.disabled_toolsets tidak menutup jalur ini pada 0.20.4. Cron sudah melakukannya dan bug tetap terjadi. skip_memory=True juga belum cukup jika enabled toolset masih menyebut memory.
3. Matikan kedua injeksi built-in bila dampaknya dapat diterima
Workaround konfigurasi yang paling langsung adalah menonaktifkan dua blok built-in:
memory:
memory_enabled: false
user_profile_enabled: false
Ini bersifat global. Percakapan normal juga tidak akan menerima MEMORY.md dan USER.md, jadi jangan menerapkannya tanpa memahami dampak ke workflow utama. Backup konfigurasi, ubah secara terukur, restart sesuai prosedur instalasi, lalu lakukan smoke test.
4. Pisahkan profile cron dari memory sensitif
Jika operasi membutuhkan cron tetap aktif, jalankan job pada profile atau home terpisah yang tidak menyimpan memory sensitif. Jangan menyalin MEMORY.md, USER.md, credential, atau catatan bisnis ke profile tersebut hanya demi menyamakan konteks.
Pemisahan ini tidak memperbaiki bug, tetapi memperkecil data yang tersedia saat bug terjadi.
5. Jangan menganggap mengambil commit dari main sebagai upgrade production
PR masih open. Menjalankan branch atau cherry-pick lokal dapat berguna untuk reproduksi di staging, tetapi menambah beban patch management dan belum memiliki jaminan rilis. Untuk production, tunggu merge dan tag yang secara eksplisit memuat fix.
Cara memverifikasi release berikutnya
Setelah upstream merilis versi yang membawa patch, uji di profile non-production.
Buat MEMORY.md dan USER.md dummy dengan marker unik yang tidak sensitif. Jalankan cron tanpa tool memory dan minta job melaporkan hanya apakah marker tersedia, bukan mencetak nilainya. Marker seharusnya tidak terlihat. Periksa juga konfigurasi efektif dan log startup agent bila tersedia.
Lanjutkan dengan tiga cek:
- cron biasa tetap berjalan dan mengirim hasil;
- memory tool tidak tersedia di job;
- percakapan interaktif yang memang memakai memory tetap mendapat konteksnya.
Jangan hanya melihat bahwa CI upstream hijau atau command cron berstatus sukses. Acceptance criteria untuk bug ini adalah file memory tidak dibaca dan tidak masuk ke prompt cron.
Keputusan operasional
Hermes Agent 0.20.4 masih menjadi release tagged terbaru saat audit 21 Agustus 2026. Belum ada release pengganti yang membawa fix P1 ini.
Jika instalasi memakai cron untuk output privat ke pemilik yang sama dan memory tidak berisi data sensitif, risikonya lebih terbatas, tetapi bug tetap perlu dicatat. Jika cron mengirim ke grup, client, webhook, atau sistem lintas tim, tahan rollout dan audit job sekarang.
PR #91270 sudah berada di jalur yang benar dan required checks lulus. Sampai patch merged serta masuk tag resmi, anggap skip_memory=True pada cron 0.20.4 belum menjadi batas privasi yang dapat dipercaya.
Referensi resmi
- Hermes Agent 0.20.4 / v2026.8.18
- Issue #91269: Cron jobs load MEMORY.md even though skip_memory is on
- PR #91270: do not load MEMORY.md into scheduled jobs
- Source cron scheduler pada v2026.8.18
- Source agent init pada v2026.8.18
- Source system prompt pada v2026.8.18
- Konfigurasi memory pada v2026.8.18
- Hermes Agent Security Policy


