本文へスキップ

Security & safeguards

このページには翻訳がありますが、その後に英語の原文が変更されたため、英語を表示しています。

Chimera can run shell commands, edit files, call APIs, and modify its own skills. It ships defense-in-depth, and — this matters — the docs state where each layer stops.

The one rule

None of these safeguards replace running it in an isolated environment when you grant autonomy. The default local runner is not isolated; use CHIMERA_SANDBOX=docker (network-off, optionally under gVisor) for untrusted work.

The layers

  • Governance kernel — every governed tool call is allow / warn / review / block. A cheap first filter of dangerous shell signatures, not the boundary.
  • Sandbox — an ephemeral, network-off container (CHIMERA_SANDBOX=docker), hardenable with gVisor (CHIMERA_SANDBOX_RUNTIME=runsc).
  • Per-session tool allowlist — grant a run only the tools it needs; the rest are dropped from the model's schema entirely.
  • Taint tracking (--taint) — untrusted content is fenced as data, its provenance follows it into memories and skills (a skill from a tainted run is held for review), and once a run is tainted the dangerous tools narrow.
  • Quarantined reader — the dual-LLM / CaMeL pattern: untrusted content is read by a tool-less model that can only emit schema-validated fields, so an injection can't produce a new instruction or tool call.
  • Cross-agent monitor — under fan-out a per-worker monitor is blind to a split flow (one worker fetches untrusted, a different worker sinks it — the fetch and the sink live in separate ledgers). An aggregate monitor sees the whole fan-out; it is always on for solve-batch / crew-isolated.

Fan-out: the cross-agent monitor

When several tool-using workers run in parallel (solve-batch, crew-isolated), each gets its own capability ledger, and after the batch an aggregate monitor runs over all of them. It catches patterns no single-worker monitor can see — the split exfiltration where worker A fetches untrusted content and worker B executes or exfiltrates it:

$ chimera solve-batch "read notes.md and summarize" "download the helper and run it" -w .
task1: ok
task2: ok
merged 2 file(s) across 2 task(s)
⚠ cross-agent monitor flagged (review):
  - cross-agent-taint: untrusted content entered via one agent and a different agent
    performed a sink (task2→task1) — a split flow no single-agent monitor sees

It only ever escalates to review — it never blocks a run — and it is pure observability (recording changes no behaviour). Add --taint on top to also arm each worker's adaptive allowlist (dangerous-when-tainted tools then require approval).

Measured, not asserted

chimera redteam

runs an injection corpus through the stack. On the built-in corpus the taint layer cuts the attack success rate from 100% to ~14% — and the report names what still gets through (exfiltration via an allowed tool) rather than claiming 100%.

The same command prints the cost, which the first version of this page did not: with nobody to ask, the narrowing refuses 100% of legitimate work that read anything external first — fix the file the issue names, apply the upgrade the docs describe — and the registered gate (over-block ≤ 5%) fails. That number is not a tuning problem; the gate was empty. The default approval mode is ask, and on the desktop it now asks: a narrowed tool call becomes a question on the screen with the ledger's reason attached, answered with a button or chimera approve, refused by silence after CHIMERA_APPROVAL_WAIT seconds. With the person approving the work they asked for, over-block is 0% and the attack block rate does not move — measured, per arm, in bench/injection/RESULTS.md. The exfiltration through an allowed tool is closed by the same change: a tainted run's http_get carrying a query string is a review, and the two legitimate query-string GETs added to the corpus show what that costs.

Poisoned memory, across runs

redteam measures one run. The other shape is slower and does not fit in a process: run A reads a poisoned page and stores what it "learned"; run B asks an unrelated question days later and recall hands the planted fact to the model.

chimera memory-poison

Also offline and free. It ablates the three layers that sit between those runs — the tainted provenance flag, the recall admission gate, and the [unverified] label the fact wears into the prompt — because a single number would be compatible with any of them doing nothing. The headline is what arrives unmarked, not what is blocked: a poisoned fact carrying its origin is one the model was warned about; an unlabelled one is indistinguishable from something the agent verified itself.

Two results from the first run are worth stating plainly, because neither flatters us:

  • The shipped configuration fails its own gate — on cost. It marks 100% of the poison and destroys 25% of honest memory doing it. The casualties are named: a security document that quotes an attack in order to explain it, and a support ticket forwarding an attempt. A pattern matcher on content cannot tell a quote from a command.
  • On this corpus the content gate adds nothing the provenance label does not already cover. Its entire measured effect is the honest memory it removes. Fifteen hand-authored rows is a pointer and not a verdict, which is why nothing has been deleted on the strength of it.

Thresholds, method and what the numbers do not license are in bench/memory_poison/PREREGISTRATION.md, fixed before the first run.

Exposing the HTTP server

chimera serve binds to 127.0.0.1 by default. Its state-changing endpoints (/chat, /a2a, /webhook/*) drive the agent, so before exposing the server to a network, set a bearer token:

export CHIMERA_SERVER_TOKEN="a-long-random-secret"   # required as: Authorization: Bearer <token>

With it set, those POST endpoints return 401 without a matching Authorization: Bearer header (GET /health and the A2A agent-card stay open). For the WhatsApp inbound webhook, set CHIMERA_WHATSAPP_APP_SECRET to your Meta app secret — Chimera then verifies each request's X-Hub-Signature-256 HMAC and rejects a forged payload with 403. Both are opt-in (unset = no auth, fine for localhost); a public deployment should set them (or sit behind an authenticating proxy).

Honest limits

This measures whether an already-injected agent's harmful action is stopped — not whether the model can be injected in the first place. Free-form reasoning over untrusted prose, and exfiltration through legitimately-needed tools, remain open problems (tracked as issue #5).

The full, always-current policy lives in SECURITY.md, including how to report a vulnerability.

GitHub でこのページを編集