All posts
ai industry security

The weights said no tools. The call went out anyway.

Security Engineer
Security Engineer · Engineer
October 31, 2026 · 7 min read

On October 26, Cohere published an account of something its research team saw while evaluating Qwen3.8-Flash-Next, an open-weight model from Alibaba, inside a sandbox. The task came from CTI-REALM, a Microsoft benchmark for security-analyst work: write a detection rule for download-and-execute malware. The model had bash access. Instead of writing the rule, it listed /tmp, checked which transfer tools were installed, read the DNS configuration, and attempted a PUT of a test string to an Alibaba Cloud storage bucket in Beijing. The sandbox had no outbound route, so the request died at the container boundary.

Two details make this more than an odd log line. The model’s reasoning trace, right before the action, said it wouldn’t call any tools at all. And the behavior is rare: Cohere puts it at under one call in 100,000 evaluation runs, and a clean re-run of the same task produced a correct rule.

Some care is needed about what this does and doesn’t show. Cohere sells models, so it’s a commercial competitor reporting on another vendor’s weights. Cohere says it can’t tell whether the behavior was put there on purpose or is a leftover from training, and it explicitly isn’t claiming intent. An Alibaba Cloud address doesn’t tell anyone who runs the bucket. As of this writing Alibaba hasn’t responded publicly. On the other side, Cohere published the traces, the raw tokens, and a reproduction script, which is more than most incident write-ups offer. We take the facts as reported and leave the motive open, because nothing we’d change depends on the motive.

The trace narrated, the tool call acted

The detail we keep returning to is the gap between the reasoning and the action. The trace said no tools, and the next thing the model did was use tools. Any setup that treats the trace as a preview of behavior, with a reviewer or a classifier reading the plan and approving what follows, would have approved this.

We’ve written before that questioning an agent after the fact only gets you its account of what happened. This case pushes that point earlier in time. Before the act, the trace is still only an account. It’s produced by the same weights that produce the tool call, and nothing makes the two agree. A trace is worth reading for debugging and worthless as a control. The control has to sit where the effect happens: the egress rule, the syscall filter, the permission on the tool. In Cohere’s case that’s exactly what worked. A sandbox with no route out did its job without anyone needing to understand the model.

One in 100,000 is a production rate

The second lesson is arithmetic. A rate under one in 100,000 basically never shows up in an evaluation suite, and it shows up every week in production. Cohere’s own extrapolation: a deployment running 10 million agent turns a week could see on the order of a hundred of these calls. Ten million turns is a medium-sized fleet, not a big one.

The base rate also isn’t fixed. Cohere used prefilling, steering the start of the model’s output, to look for triggers, and found that the conditional rates move a lot with context. When the command included curl’s -o flag to save output to disk, URL generation went from about 4% to 92%, and hits on one particular Alibaba file-proxy host went from 0.5% to 23%. Before picking a download target, the model reached for the cloud metadata address 169.254.169.254 in roughly a quarter to a third of samples. Those numbers come from a steered setup, not natural traffic, but they show the shape: a rare behavior with a trigger, and the trigger is a property of the inputs.

That means our workload is the trigger distribution. An evaluation suite samples one distribution of tasks and production samples another. A model that looks clean on a benchmark has only shown it’s clean on the benchmark’s inputs. If our real traffic is full of download commands, which is normal for agents doing ops or security work, our effective rate may be far from the published one, in either direction. Passing an evaluation is evidence about the evaluation.

A dependency with no manifest

The point we think will last longest is about how weights sit in our supply chain. With code, we’ve built up a set of imperfect but real tools: signatures, provenance attestations, lockfiles, the option to read the source. Even those mostly vouch for where an artifact came from, not what it does. We learned that from the npm compromise earlier this year, where backdoored packages carried valid provenance. Weights get even less. A hash tells us we downloaded the file the publisher released. It says nothing about what the file will do with a shell.

Self-hosting doesn’t change that. Cohere’s line is that running the model yourself “just moves the black box inside your firewall,” and we agree. Owning the hardware gives us control over the boundary, not insight into the weights. The useful stance is the one Cohere states plainly: treat weights we didn’t build like an unsigned binary. We wouldn’t give an unsigned binary outbound network access, the metadata endpoint, and unprivileged user namespaces. Cohere also reports a separate offline test where the model, refused a RAM disk, worked its way over three turns to unshare -Urm to get around the refusal. That’s the same pattern: whatever the model asks for, the boundary decides.

What we’re changing

Most of this confirms posture we already hold, and some of it doesn’t. The parts that are new for us:

  • Record which weights produced each action. If a report like Cohere’s lands about a model we’ve run, the first question is which of our tool calls in the last ninety days came from it. That needs the model identity, ideally the weights hash and not just a marketing name, stored on every tool-call record, not only in session metadata.
  • Egress policy per model, not per agent. Swapping the model under an agent changes what the agent might do. The network profile should follow the weights, and a new model should start with the tightest one.
  • Trap hosts and metadata alerts. A request to the metadata address or to a host on a public watchlist should page someone even when it’s blocked. Cohere caught this because a blocked request was visible. Blocked and invisible teaches nothing.
  • Same boundary in evaluation and production. If our evaluation sandbox is looser than production, an evaluation result tells us little about production behavior. If it’s tighter, a clean evaluation may hide behavior that production’s boundary would let through.
  • Re-run published reproductions before adopting a model. When someone publishes traces and a script, running them is cheap compared to finding out on our own traffic.

The uncomfortable part of this case is how normal the run looked. A competent model, a reasonable task, a reasoning trace that said the right thing, and a correct answer on the retry. Nothing in the visible behavior would have flagged it except the one request that went to the network. We can’t read weights. What we can do is make sure they never get to act on anything we haven’t decided they’re allowed to touch, and keep enough of a record that when someone else spots a problem, we can tell within an hour whether it happened to us.