Thirteen threats, each with a primary control and a fallback. Nothing here relies on the agent behaving well.
T1A stranger sends commandsMandatory allowlist; the gateway refuses to start without one. The operator pairs from the terminal, and a group is confirmed by a signed button in the DM of that same operator.
T2Direct prompt injectionApproval arrives only as a signed callback with a nonce. Text cannot approve itself.
T3Indirect injection via README or issueClaude owns content handling and tool policy. Caraka never turns agent output or ordinary chat text into approval.
T4Secret exfiltration through a replyOutbound text and audit details are scrubbed, including the shape of a Discord bot token. No variable whose name starts with CARAKA_ reaches an agent subprocess.
T5Destructive actionCaraka relays every ACP permission request and /stop sends session/cancel. Claude decides which tools require permission.
T6Leaking into a groupA group message needs its chat and its sender on the allowlists, and pairing is confirmed in the operator DM. Caraka never asks for group admin, so a bot left in privacy mode reads only commands and replies to itself. Every member of a paired group sees the approval cards, paths, and command output.
T7Gateway exposed to the internetTelegram is polled, Discord and the Baileys provider hold outbound sockets, so those open nothing. Two listeners exist and both bind 127.0.0.1: caraka dashboard, GET only and read-only, and since v0.6 the Cloud API webhook, which verifies X-Hub-Signature-256 in constant time even on loopback. Binding either anywhere else needs an explicit flag, which prints a warning and writes an audit row first.
T8Plugin supply chainNo marketplace or dynamic loading. Four direct runtime dependencies, pinned in package-lock.json. Baileys is an exact-version optional peer, so an install that does not choose it never downloads it — and CI never installs it either, which means npm audit does not see it.
T9WhatsApp account banReal, unpredictable, and only partly ours to reduce. Four mitigations are code that can fail: allowFrom is mandatory, one outbound function caps sends at 12 per rolling minute, spaces them 1,200–3,500 ms apart, and refuses to write to any number that has not written first. Choosing the unofficial provider stops start until acknowledgeRisk: true is written, and the message links the risk page. The fifth signal, datacenter traffic, is not ours to answer at all. Cloud API is the way out and carries none of this.
T10Runaway costTasks run serially. Caraka has no model provider, reasoning loop, heartbeat, or background scheduler.
T11No way to auditSQLite records inbound, outbound, runs, approvals, and errors; triggers reject audit updates and deletes.
T12Memory poisoningRecalled text is labelled as data, its memory markers are stripped so it cannot pose as instruction, and the injected context is capped at 6 items in 800 tokens.
T13Forged approval callbackThe payload stays server-side and only an HMAC-signed id travels — 33 characters, inside both Telegram’s 64-byte callback_data and Discord’s custom_id.