ISO/IEC 27001:2022 audits passed with zero nonconformities.Find out more
A robot interacts with three screens. Each pane displays a different version of Claude: Claude Code, Claude Code in the cloud and Cowork.

One vendor, three platforms: governing Claude Code and Cowork

Oct 20, 20267 Min

TL;DR

  • Claude Code, Claude Code in the cloud and Cowork run the same build, but for anyone administering them they behave as three platforms: plugin delivery, configuration, hooks, updates, network rules and status reporting all differ.
  • No single admin channel reaches all three. A plugin marked Required in the catalogue loads only on Cowork, and managed settings reach the terminal and the cloud sandbox but never Cowork, so one plugin everywhere means two admin pages kept in step by hand.
  • Plugin secrets marked sensitive skip the keychain when the organization delivers the plugin and land in a plain settings file every user can read. On Cowork we found nowhere to set plugin configuration at all.
  • Enforcement is uneven: the hook response that blocks a prompt on the terminal and the cloud leaves a Cowork session stuck, allowManagedHooksOnly silences plugin hooks rather than user hooks, and plugin updates can take hours or never arrive while settings changes land within about an hour.
  • Treat each surface as its own platform, test behaviour instead of trusting the documentation, and establish coverage from outside the client, because several of its own status reports were wrong.

Claude now reaches people through three surfaces. Claude Code runs in a terminal on the developer's machine. Claude Code in the cloud runs the same agent in a sandbox Anthropic hosts. Cowork brings that agent to knowledge work, inside a virtual machine on the desktop or in the cloud. Same company, same agent, and in our measurements the same build on all three.

If you are responsible for governing how that agent behaves across a company, the shared lineage suggests one control plane. In practice there are three. Over several weeks we tested how each surface handles the things an administrator depends on: getting software onto it, configuring that software, enforcing policy through hooks, shipping updates, reaching the network, and reporting its own state. On almost every one of those, the three surfaces disagree.

Manifold is built to secure agents on all three surfaces, and that is what drove this work: we wanted our coverage to rest on how each surface behaves, not on how it is documented.

Because every surface ran the same build, none of the differences below are version skew. They are properties of the surface, and upgrading the client will not fix them.

No single channel reaches all three

Anthropic gives administrators two ways to push a plugin to their users. The organization's plugin catalogue lets an admin mark a plugin Required. Managed settings, configured on a different admin page, can register a marketplace and force-enable plugins from it.

Neither reaches everyone. A Required plugin arrives on Cowork, and only on Cowork, once the desktop app restarts: the terminal at most downloads it and never loads it, and the cloud sandbox does not download it at all. Managed settings work the other way round. They reach the terminal and the cloud sandbox, and Cowork receives none of them. A public bug report against Claude Code describes the same gap and the reason for it: Cowork runs in a Linux VM, so it looks for managed settings on a Linux path, while the device's own settings live on the host and the VM never reads them (anthropics/claude-code#40495, open at the time of writing).

What this means is each channel misses a surface the other one reaches. Cowork can only be reached through the catalogue, while the terminal and the cloud sandbox only through managed settings. Getting one plugin onto all three surfaces takes both channels, set up on two different admin pages and kept in step by hand. Its configuration follows the same split: values an admin sets in managed settings travel only where managed settings do, so a plugin delivered to Cowork receives none of them.

Configuration has nowhere safe to go

Plugins can declare configuration, including values marked sensitive, which are meant to be stored in the system keychain. That path runs through a prompt the user sees when they enable the plugin themselves. A plugin distributed by the organization never shows that prompt, so the flag does nothing: values sent through managed settings land in a plain settings file, readable in clear text in every session. A secret an admin hands to a plugin this way is, in practice, handed to every user of that plugin.

On Cowork the problem starts earlier. We found no place, neither in the admin console nor in Cowork itself, where a plugin's declared configuration could be set at all.

The same hook, three outcomes

Hooks are how policy becomes enforcement: a script that runs before a tool call or a prompt and can allow or deny it. This is where the surfaces diverge most.

A hook that denies a tool call works identically everywhere. A hook that blocks a prompt does not. The response shape that blocks a prompt on the terminal and in the cloud leaves a Cowork session stuck, and in our tests it never recovered. The alternative shape, the one that looks like the documented equivalent, is silently ignored on all three. So there is no single prompt-level control that behaves the same across surfaces.

Two further behaviours surprised us:

  • Hooks stack rather than replace. On the terminal, hooks declared in a user's settings and hooks shipped in a plugin both fire, in a fixed order. A machine that carries both reports every event twice.
  • allowManagedHooksOnly does not do what its name says. It left hooks in the user's own settings running and silenced the hooks that came from plugins, even force-enabled ones. It also only took effect when delivered as a settings file on the device. Set from the admin console, the same key was ignored, on the terminal and in the cloud alike. While its hooks were blocked, the plugin went on reporting itself as enabled.

Three clocks for updates

Publishing a new version of a plugin does not mean users run it, and how long it takes depends on the surface.

On the terminal, it may never happen on its own. The marketplace is cloned once and cached on disk. Refreshing that cache and upgrading the plugin are two separate commands, plus a restart, and over several hours of observation nothing did either automatically.

In the cloud sandbox, each session clones the marketplace when it starts and never refreshes it. The install itself is asynchronous: in one measurement the plugin loaded ten minutes into the session, and in another between 48 and 82 minutes after its marketplace was registered. Until then the session runs without the plugin's hooks, and a session shorter than that window never runs them at all.

On Cowork, a new version reaches new sessions, but only after the desktop app restarts. A running session was never seen to update.

Configuration has a clock of its own, and it is the fastest. Settings changes reached clients within about an hour, ahead of the plugin version they were written for. The result is an old plugin, still loaded and firing, running on configuration written for a newer version.

Two allowlists, in two consoles

From both remote surfaces, only one kind of traffic leaves the sandbox: port 443, to a domain on an allowlist. On any other port the proxy accepts the connection and then resets it, which from the outside looks like the destination server failing rather than a policy decision.

The allowlists themselves live in different places. Cowork's is set once for the organization, by an owner, and binds every session. The cloud sandbox's is set per environment, by each user who creates one, and defaults to a trusted list of common developer hosts. An organization that wants both surfaces to reach the same destination configures it twice, in two consoles, and can only enforce the Cowork one.

When a connection is refused, Cowork says so and names the policy. The cloud sandbox reports the same refusal as a transport error.

Two smaller findings from the cloud sandbox belong here too. A user's own configuration does not survive from one session to the next, so the only setting that persists is one committed to the repository. And the sandbox ships hook scripts of its own, placed there by the platform, which run beside anything the customer or a vendor installs.

Signals you cannot build on

An administrator's natural question is "is it installed and running?" The answers the surfaces give were wrong more often than we expected:

  • In the cloud sandbox, the /plugin command reports that plugins are not available in that environment. They are: they load and enforce.
  • Asked to disable a force-enabled plugin, the cloud sandbox reports success and lists the plugin as disabled. It keeps running.
  • The file that records installed plugins shows the version a client intends to run, not the one any open session has loaded.
  • failed to load appears both while an install is still settling and when a plugin is genuinely broken, with nothing to tell the two apart.
  • The plugin console numbers uploads with its own counter, so the version an admin sees there is not the version the plugin declares.
  • The environment variable that identifies the surface is inherited by child processes, so a nested invocation reports the surface that launched it, and headless runs report a value distinct from the interactive terminal.

Each of these is small. Together they mean that no status a client reports about itself is safe to use as evidence of coverage.

What to do if you govern Claude across all three surfaces

None of this is a criticism of the individual surfaces. Each is a reasonable design for its audience. The difficulty is that they behave as if they were designed separately, and the administration layer has not caught up with the fact that one company now ships three platforms under one name. A few things follow for anyone trying to govern them:

  • Treat each surface as its own platform. Plan delivery, configuration and enforcement per surface, and expect them to differ.
  • Measure, then trust. Some behaviours above contradict the documentation, including how the terminal handles synced plugins and what allowManagedHooksOnly blocks. Behaviour changes faster than documentation.
  • Assume version skew is permanent. Settings, plugins and sessions move on different clocks, so something will always be running against configuration newer or older than itself.
  • Do not take a client's word for its own state. Whether an agent is covered is something to establish from outside the client, not to read from it.

Manifold's coverage of Claude is built on these findings: one view across the terminal, the cloud sandbox and Cowork, designed around the differences above.

The fragmentation people usually worry about is across vendors. It already exists inside one.

Behaviour as observed between September and October 2026. Every finding above comes from a direct observation on the surface named, not from documentation; where we could not reproduce a result, we left it out. The platform changes quickly, and some of this may already have moved.

About the author

  • Guido Bonomi

    Guido Bonomi

    Member of Technical Staff

    Guido Bonomi is a Member of Technical Staff at Manifold, where he works on runtime security for AI agents, building the systems that help security teams understand agent behaviour on endpoints, assess the risks it creates, and detect and respond to threats.